-
Notifications
You must be signed in to change notification settings - Fork 10
66 lines (60 loc) · 2.79 KB
/
Copy pathdecide.yml
File metadata and controls
66 lines (60 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Event-driven review: fires on every comment on a paper-review issue by the
# reviewer, applies /approve /reject /edit commands to data/, re-renders the
# README, feeds /edit corrections to calibration.json, and closes the issue
# when every paper is decided. No polling, no cron, no Claude token needed.
name: Apply review decisions
on:
issue_comment:
types: [created]
permissions:
contents: write
issues: write
# No concurrency group on purpose. decide is idempotent and the push step below
# self-heals against concurrent writers by re-running on fresh main. A shared
# group would instead let GitHub silently CANCEL a queued run (it keeps only one
# pending run per group), which would drop that issue's approvals with no error.
# Tolerate concurrency with idempotent retry; never prevent it by dropping events.
jobs:
decide:
# Defense in depth: the workflow gate checks the reviewer login, and
# pipeline.decide independently trusts only config.yaml's repo.reviewer.
if: >
!github.event.issue.pull_request &&
contains(github.event.issue.labels.*.name, 'paper-review') &&
github.event.comment.user.login == 'Zhaoyang-Chu'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: pip install pyyaml
- name: Apply decisions and push (idempotent, concurrency-safe)
env:
GH_TOKEN: ${{ github.token }}
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
issue="${{ github.event.issue.number }}"
# decide is stateless and dedup-safe, so each attempt re-derives the
# decision from the issue's full comment history against the LATEST
# main. A lost push race just means we reset to the new main and re-run;
# the generated views never conflict because we regenerate, not merge.
for attempt in 1 2 3 4 5; do
git fetch --quiet origin main
git reset --quiet --hard origin/main
python -m automation.pipeline decide --issue "$issue"
git add README.md assets/ automation/
if git diff --cached --quiet; then
echo "Nothing to commit (already applied on main)."
exit 0
fi
git commit --quiet -m "feat(data): papers approved in review issue #$issue"
if git push --quiet; then
echo "Pushed on attempt $attempt."
exit 0
fi
echo "Push lost a race with a concurrent write; retrying on fresh main (attempt $attempt)."
sleep $((RANDOM % 5 + 2))
done
echo "::error::Could not push decision for issue #$issue after 5 attempts."
exit 1