koth-ledger #218
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # appends dethrone rows to competition/LEADERBOARD.md for merged ladder | |
| # PRs. the scoring gates stay read-only by design (the engine gate holds | |
| # no write token at all); this workflow never runs on a PR event, so an | |
| # untrusted PR can never reach its write token. | |
| # | |
| # it is a SWEEP, not a per-push hook: the gate arms auto-merge with the | |
| # workflow GITHUB_TOKEN, and github's recursion guard suppresses workflow | |
| # triggers for pushes caused by that token — so an auto-merged dethrone | |
| # never fires a push event here (round 1, PR #566, proved it live). the | |
| # push trigger still catches human-merged rows immediately; the schedule | |
| # and manual dispatch pick up auto-merged ones. update_leaderboard.py is | |
| # idempotent per PR, so overlapping sweeps converge instead of duplicating. | |
| name: koth-ledger | |
| on: | |
| push: | |
| schedule: | |
| - cron: "17 */6 * * *" | |
| workflow_dispatch: | |
| permissions: {} | |
| concurrency: | |
| group: koth-ledger | |
| cancel-in-progress: false | |
| jobs: | |
| ledger: | |
| if: >- | |
| vars.KOTH_LADDER_BASE != '' && | |
| (github.event_name != 'push' || | |
| (github.ref_name == vars.KOTH_LADDER_BASE && | |
| !startsWith(github.event.head_commit.message, 'docs(competition): ledger row'))) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: read | |
| steps: | |
| # the push token: the ladder ruleset requires the gate check on every | |
| # push, and the workflow GITHUB_TOKEN holds no bypass, so rows are | |
| # pushed with an owner token (repo secret). safe because this workflow | |
| # never runs on PR events and never executes untrusted code — the only | |
| # inputs are gate-authored comments parsed as json. | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ vars.KOTH_LADDER_BASE }} | |
| token: ${{ secrets.KOTH_LEDGER_TOKEN || github.token }} | |
| - name: append rows for recently merged ladder prs | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| LADDER: ${{ vars.KOTH_LADDER_BASE }} | |
| run: | | |
| gh pr list --repo "$GITHUB_REPOSITORY" --base "$LADDER" \ | |
| --state merged --limit 15 --json number,author \ | |
| --jq '.[] | "\(.number) \(.author.login)"' > /tmp/merged.txt | |
| appended=0 | |
| while read -r pr author; do | |
| [ -n "$pr" ] || continue | |
| # only the gate's own comments are trusted: a scorecard-shaped | |
| # comment from anyone else must never reach the ledger | |
| gh api "repos/${GITHUB_REPOSITORY}/issues/${pr}/comments" \ | |
| --paginate \ | |
| --jq '.[] | select(.user.login == "github-actions[bot]") | .body' \ | |
| > /tmp/comments.txt || continue | |
| rm -f /tmp/report.json | |
| python3 - <<'PYEOF' | |
| import re | |
| body = open("/tmp/comments.txt", encoding="utf-8").read() | |
| blocks = re.findall(r"```json\n(.*?)\n```", body, flags=re.S) | |
| reports = [b for b in blocks if '"dethroned": true' in b] | |
| if reports: | |
| with open("/tmp/report.json", "w", encoding="utf-8") as fh: | |
| fh.write(reports[-1]) | |
| PYEOF | |
| if [ -f /tmp/report.json ]; then | |
| python3 .github/scripts/update_leaderboard.py \ | |
| --report /tmp/report.json --pr "$pr" --author "$author" \ | |
| && appended=1 | |
| # the ratchet: a merged engine-lane dethrone becomes the new | |
| # champion, so the next challenger's merge threshold rises | |
| # automatically. the winner is the single strategy file the | |
| # pr added. | |
| lane=$(jq -r '.lane // "kit"' /tmp/report.json) | |
| if [ "$lane" = "engine" ]; then | |
| mean=$(jq -r '.challenger.mean' /tmp/report.json) | |
| winner=$(gh api "repos/${GITHUB_REPOSITORY}/pulls/${pr}/files" \ | |
| --paginate \ | |
| --jq '.[] | select(.status != "removed") | .filename' \ | |
| | grep -E '^contrib/strategies/[A-Za-z0-9_]+\.py$' \ | |
| | grep -v 'baseline\.py' | head -1 || true) | |
| if [ -n "$winner" ] && [ -f "$winner" ]; then | |
| python3 .github/scripts/promote_champion.py \ | |
| --strategy "$winner" --pr "$pr" --mean "$mean" | |
| fi | |
| fi | |
| fi | |
| done < /tmp/merged.txt | |
| echo "sweep done (appended=$appended)" | |
| - name: commit the rows | |
| run: | | |
| if git diff --quiet -- competition/LEADERBOARD.md; then | |
| echo "ledger unchanged" | |
| exit 0 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add competition/LEADERBOARD.md | |
| git commit -m "docs(competition): ledger rows from sweep" | |
| git push |