Skip to content

Commit bc0f120

Browse files
committed
ci(competition): ledger sweeps merged prs - auto-merge pushes fire no events
round 1 (pr #566) proved the gap live: the gate arms auto-merge with the workflow GITHUB_TOKEN, and github suppresses workflow triggers for pushes caused by that token, so the merge push never reached the ledger. the workflow now sweeps recently merged ladder prs (schedule + manual dispatch + the still-working push path for human merges); the appender stays idempotent per pr, so overlapping sweeps converge.
1 parent 6a992ba commit bc0f120

1 file changed

Lines changed: 46 additions & 53 deletions

File tree

.github/workflows/koth-ledger.yml

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,60 @@
1-
# appends the dethrone row to competition/LEADERBOARD.md after a win lands
2-
# on the ladder branch. the scoring gates stay read-only by design (the
3-
# engine gate holds no write token at all); this workflow never runs on a
4-
# PR event — only on push to the ladder branch, after the merge, from
5-
# base-branch code — so an untrusted PR can never reach its write token.
6-
# idempotent: update_leaderboard.py no-ops when the PR is already cited,
7-
# so the workflow triggering on its own ledger push converges.
1+
# appends dethrone rows to competition/LEADERBOARD.md for merged ladder
2+
# PRs. the scoring gates stay read-only by design (the engine gate holds
3+
# no write token at all); this workflow never runs on a PR event, so an
4+
# untrusted PR can never reach its write token.
5+
#
6+
# it is a SWEEP, not a per-push hook: the gate arms auto-merge with the
7+
# workflow GITHUB_TOKEN, and github's recursion guard suppresses workflow
8+
# triggers for pushes caused by that token — so an auto-merged dethrone
9+
# never fires a push event here (round 1, PR #566, proved it live). the
10+
# push trigger still catches human-merged rows immediately; the schedule
11+
# and manual dispatch pick up auto-merged ones. update_leaderboard.py is
12+
# idempotent per PR, so overlapping sweeps converge instead of duplicating.
813
name: koth-ledger
914
on:
1015
push:
16+
schedule:
17+
- cron: "17 */6 * * *"
18+
workflow_dispatch:
1119
permissions: {}
1220
concurrency:
13-
group: koth-ledger-${{ github.ref_name }}
21+
group: koth-ledger
1422
cancel-in-progress: false
1523
jobs:
1624
ledger:
1725
if: >-
1826
vars.KOTH_LADDER_BASE != '' &&
19-
github.ref_name == vars.KOTH_LADDER_BASE &&
20-
!startsWith(github.event.head_commit.message, 'docs(competition): ledger row')
27+
(github.event_name != 'push' ||
28+
(github.ref_name == vars.KOTH_LADDER_BASE &&
29+
!startsWith(github.event.head_commit.message, 'docs(competition): ledger row')))
2130
runs-on: ubuntu-latest
2231
permissions:
2332
contents: write
2433
pull-requests: read
2534
steps:
2635
- uses: actions/checkout@v4
2736
with:
28-
ref: ${{ github.ref_name }}
37+
ref: ${{ vars.KOTH_LADDER_BASE }}
2938

30-
- name: find the merged pr and its scorecard comment
31-
id: scorecard
39+
- name: append rows for recently merged ladder prs
3240
env:
3341
GH_TOKEN: ${{ github.token }}
34-
SHA: ${{ github.sha }}
42+
LADDER: ${{ vars.KOTH_LADDER_BASE }}
3543
run: |
36-
pr_json="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${SHA}/pulls" \
37-
--jq '[.[] | select(.merged_at != null)][0] // empty')"
38-
if [ -z "$pr_json" ]; then
39-
echo "no merged pr for ${SHA}; nothing to ledger"
40-
echo "found=false" >> "$GITHUB_OUTPUT"
41-
exit 0
42-
fi
43-
pr_number="$(printf '%s' "$pr_json" | jq -r '.number')"
44-
pr_author="$(printf '%s' "$pr_json" | jq -r '.user.login')"
45-
# only the gate's own comments are trusted: a scorecard-shaped
46-
# comment from anyone else must never reach the ledger
47-
gh api "repos/${GITHUB_REPOSITORY}/issues/${pr_number}/comments" \
48-
--paginate \
49-
--jq '.[] | select(.user.login == "github-actions[bot]") | .body' \
50-
> /tmp/comments.txt
51-
python3 - <<'PYEOF'
44+
gh pr list --repo "$GITHUB_REPOSITORY" --base "$LADDER" \
45+
--state merged --limit 15 --json number,author \
46+
--jq '.[] | "\(.number) \(.author.login)"' > /tmp/merged.txt
47+
appended=0
48+
while read -r pr author; do
49+
[ -n "$pr" ] || continue
50+
# only the gate's own comments are trusted: a scorecard-shaped
51+
# comment from anyone else must never reach the ledger
52+
gh api "repos/${GITHUB_REPOSITORY}/issues/${pr}/comments" \
53+
--paginate \
54+
--jq '.[] | select(.user.login == "github-actions[bot]") | .body' \
55+
> /tmp/comments.txt || continue
56+
rm -f /tmp/report.json
57+
python3 - <<'PYEOF'
5258
import re
5359
5460
body = open("/tmp/comments.txt", encoding="utf-8").read()
@@ -58,35 +64,22 @@ jobs:
5864
with open("/tmp/report.json", "w", encoding="utf-8") as fh:
5965
fh.write(reports[-1])
6066
PYEOF
61-
if [ ! -f /tmp/report.json ]; then
62-
echo "no gate scorecard with a dethrone on pr ${pr_number}"
63-
echo "found=false" >> "$GITHUB_OUTPUT"
64-
exit 0
65-
fi
66-
echo "found=true" >> "$GITHUB_OUTPUT"
67-
echo "pr=${pr_number}" >> "$GITHUB_OUTPUT"
68-
echo "author=${pr_author}" >> "$GITHUB_OUTPUT"
67+
if [ -f /tmp/report.json ]; then
68+
python3 .github/scripts/update_leaderboard.py \
69+
--report /tmp/report.json --pr "$pr" --author "$author" \
70+
&& appended=1
71+
fi
72+
done < /tmp/merged.txt
73+
echo "sweep done (appended=$appended)"
6974
70-
- name: append the ledger row
71-
if: steps.scorecard.outputs.found == 'true'
72-
env:
73-
PR: ${{ steps.scorecard.outputs.pr }}
74-
AUTHOR: ${{ steps.scorecard.outputs.author }}
75-
run: |
76-
python3 .github/scripts/update_leaderboard.py \
77-
--report /tmp/report.json --pr "$PR" --author "$AUTHOR"
78-
79-
- name: commit the row
80-
if: steps.scorecard.outputs.found == 'true'
81-
env:
82-
PR: ${{ steps.scorecard.outputs.pr }}
75+
- name: commit the rows
8376
run: |
8477
if git diff --quiet -- competition/LEADERBOARD.md; then
85-
echo "ledger unchanged (row already present)"
78+
echo "ledger unchanged"
8679
exit 0
8780
fi
8881
git config user.name "github-actions[bot]"
8982
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
9083
git add competition/LEADERBOARD.md
91-
git commit -m "docs(competition): ledger row for #${PR}"
84+
git commit -m "docs(competition): ledger rows from sweep"
9285
git push

0 commit comments

Comments
 (0)