Files
awesome-coding-agents/.github/workflows/update.yml
T
tiennm99 f0e10d6d26 fix(ci): narrow conflict resolution to bot-generated files only
The blanket git pull --rebase -X theirs in the push-retry loop silently
discarded conflicting changes in any file, so a maintainer push to
data/agents.yml racing with the daily run could be dropped without
warning. Replace it with a selective resolver: plain rebase first, then
inspect git diff --name-only --diff-filter=U; if every conflicting path
is data/history.jsonl or README.md (both bot-generated), resolve those
with --theirs and continue; otherwise abort the rebase and fail the run
loudly so the human edit is preserved and visible.

Also leave a comment at the permissions block warning future maintainers
not to swap GITHUB_TOKEN for a PAT, since the no-recursion invariant is
what currently prevents the auto-commit from triggering its own workflow.
2026-05-14 15:49:05 +07:00

79 lines
2.8 KiB
YAML

name: Update rankings
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
push:
branches: [main]
paths:
- 'data/agents.yml'
- 'templates/**'
- '**.go'
- 'go.mod'
- '.github/workflows/update.yml'
permissions:
# Uses GITHUB_TOKEN intentionally — a PAT would cause infinite trigger loops
# on the auto-commit ("chore: daily ranking refresh") because GITHUB_TOKEN-authored
# pushes do NOT re-trigger workflows, whereas a PAT would.
contents: write
concurrency:
group: update-rankings
cancel-in-progress: false
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 'stable'
cache: true
- name: Run updater
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: go run .
- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md data/history.jsonl
if git diff --staged --quiet; then
echo "no changes"
exit 0
fi
git commit -m "chore: daily ranking refresh"
# Rebase + retry guards against the race where two runs commit near-simultaneously.
# Strategy: plain rebase first; only force-resolve bot-generated files (README.md,
# data/history.jsonl) when they are the sole conflicts. If any human-maintained file
# (e.g. data/agents.yml) conflicts, abort and fail loudly so a human can investigate.
for attempt in 1 2 3; do
if git push; then exit 0; fi
echo "push attempt $attempt rejected, rebasing on origin/main"
if git pull --rebase origin main; then
# Clean rebase — no conflicts; loop back to try push again.
continue
fi
# Rebase stopped on conflicts. Inspect which files are unresolved.
conflicted=$(git diff --name-only --diff-filter=U)
echo "conflicted files: $conflicted"
# Only auto-resolve if ALL conflicts are in bot-generated files.
non_bot=$(echo "$conflicted" | grep -v -E '^(README\.md|data/history\.jsonl)$' || true)
if [ -n "$non_bot" ]; then
echo "ERROR: conflict in human-maintained file(s): $non_bot — aborting rebase"
git rebase --abort
exit 1
fi
# Safe to force-resolve: keep our (freshest) bot-generated content.
git checkout --theirs README.md data/history.jsonl 2>/dev/null || true
git add README.md data/history.jsonl
GIT_EDITOR=true git rebase --continue
done
exit 1