mirror of
https://github.com/Heretek-AI/awesome-opencode.git
synced 2026-11-07 02:35:58 -10:00
ci: publish the README through a self-merging bot PR
GitHub rulesets reject direct pushes while a status check is required, even when the pushed commit's check passed (verified: GH013 'Required status check "validate" is expected' on a commit with a successful validate run). The README workflow now opens a PR from bot/readme-<sha>, dispatches validate on it and squash-merges it once green; older bot README PRs are closed as superseded. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
7c166ab68f
commit
bf926fecc8
2 files changed
+53
-50
No files matched your search
@@ -10,10 +10,12 @@ on:
|
||||
- 'scripts/**'
|
||||
workflow_dispatch:
|
||||
|
||||
# main requires a passing "validate" check on every commit, so the regenerated README is first pushed
|
||||
# to a bot/readme-* branch, validated there, and then fast-forwarded onto main.
|
||||
# main requires a passing "validate" check, which rulesets only accept through a pull request merge.
|
||||
# The regenerated README therefore goes through a bot PR: branch bot/readme-<sha>, validate dispatched on
|
||||
# it, then squash-merged by this job once the check passes.
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
actions: write
|
||||
checks: read
|
||||
|
||||
@@ -29,7 +31,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
ref: main
|
||||
# Full history: "Recently added" is derived from when each entry file was first committed
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
@@ -43,7 +45,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: Generate, validate and publish README/registry
|
||||
- name: Generate, validate and merge README/registry
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
@@ -52,50 +54,51 @@ jobs:
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
for attempt in 1 2 3 4 5; do
|
||||
echo "Generation attempt ${attempt}"
|
||||
git fetch origin main
|
||||
git reset --hard origin/main
|
||||
|
||||
# Both scripts validate the whole catalog and exit non-zero without writing on any error
|
||||
node scripts/generate-readme.js
|
||||
node scripts/export-json.js --pretty --output dist/registry.json
|
||||
|
||||
if git diff --quiet -- README.md dist/registry.json; then
|
||||
echo "README.md and dist/registry.json are already current."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git add README.md dist/registry.json
|
||||
git commit -m "docs: auto-regenerate README and registry data"
|
||||
sha="$(git rev-parse HEAD)"
|
||||
branch="bot/readme-${sha:0:12}"
|
||||
|
||||
# Stage the commit and run the required "validate" check on it
|
||||
git push --force origin "HEAD:refs/heads/${branch}"
|
||||
gh workflow run validate-pr.yml --ref "${branch}"
|
||||
conclusion=""
|
||||
for i in $(seq 1 60); do
|
||||
sleep 10
|
||||
conclusion="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${sha}/check-runs?check_name=validate" \
|
||||
--jq '[.check_runs[] | select(.status == "completed") | .conclusion][0] // ""')"
|
||||
[ -n "${conclusion}" ] && break
|
||||
done
|
||||
|
||||
if [ "${conclusion}" != "success" ]; then
|
||||
git push origin --delete "${branch}" || true
|
||||
echo "validate on ${sha} finished with '${conclusion:-timeout}'; not publishing" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if git push origin "${sha}:refs/heads/main"; then
|
||||
git push origin --delete "${branch}" || true
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git push origin --delete "${branch}" || true
|
||||
echo "main moved while validating; retrying..."
|
||||
# Close bot README PRs left open by earlier failed runs; this run supersedes them
|
||||
for old in $(gh pr list --state open --search "head:bot/readme-" --json number,headRefName \
|
||||
--jq '.[] | select(.headRefName | startswith("bot/readme-")) | .number'); do
|
||||
gh pr close "$old" --delete-branch --comment "Superseded by a newer README regeneration." || true
|
||||
done
|
||||
|
||||
echo "Failed to publish regenerated README/registry after retries" >&2
|
||||
# Both scripts validate the whole catalog and exit non-zero without writing on any error
|
||||
node scripts/generate-readme.js
|
||||
node scripts/export-json.js --pretty --output dist/registry.json
|
||||
|
||||
if git diff --quiet -- README.md dist/registry.json; then
|
||||
echo "README.md and dist/registry.json are already current."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git add README.md dist/registry.json
|
||||
git commit -m "docs: auto-regenerate README and registry data"
|
||||
sha="$(git rev-parse HEAD)"
|
||||
branch="bot/readme-${sha:0:12}"
|
||||
git push --force origin "HEAD:refs/heads/${branch}"
|
||||
|
||||
pr="$(gh pr create --base main --head "${branch}" \
|
||||
--title "docs: auto-regenerate README and registry data" \
|
||||
--body "Automated by \`generate-readme.yml\` after ${GITHUB_SHA:0:12}. Merged automatically once \`validate\` passes.")"
|
||||
echo "Opened ${pr}"
|
||||
|
||||
gh workflow run validate-pr.yml --ref "${branch}"
|
||||
conclusion=""
|
||||
for i in $(seq 1 60); do
|
||||
sleep 10
|
||||
conclusion="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${sha}/check-runs?check_name=validate" \
|
||||
--jq '[.check_runs[] | select(.status == "completed") | .conclusion][0] // ""')"
|
||||
[ -n "${conclusion}" ] && break
|
||||
done
|
||||
if [ "${conclusion}" != "success" ]; then
|
||||
echo "validate on ${sha} finished with '${conclusion:-timeout}'; leaving ${pr} open for a maintainer" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The required check can take a moment to register on the PR
|
||||
for i in 1 2 3 4 5 6; do
|
||||
if gh pr merge "${pr}" --squash --delete-branch --subject "docs: auto-regenerate README and registry data"; then
|
||||
exit 0
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
echo "Could not merge ${pr}; leaving it open for a maintainer" >&2
|
||||
exit 1
|
||||
+2
-2
@@ -51,7 +51,7 @@ A weekly scout searches npm for packages published since V2 shipped that depend
|
||||
|
||||
## Branch protection
|
||||
|
||||
`main` has a ruleset: every commit that lands on it must have a passing `validate` check, and force-pushes and deletion are blocked. Contributors and maintainers get the check through pull requests; bots get it by dispatching `validate` on their branch. Repository admins can merge a PR whose check is failing or pending (for a broken CI), but cannot push unvalidated commits directly.
|
||||
`main` has a ruleset: changes land only through pull requests with a passing `validate` check (GitHub rulesets do not accept direct pushes while a status check is required), and force-pushes and deletion are blocked. Bots open PRs too and get the check by dispatching `validate` on their branch. Repository admins can merge a PR whose check is failing or pending (for a broken CI).
|
||||
|
||||
## Automation map
|
||||
|
||||
@@ -59,7 +59,7 @@ A weekly scout searches npm for packages published since V2 shipped that depend
|
||||
| :--- | :--- | :--- |
|
||||
| `validate-pr.yml` | every PR | Required `validate` check |
|
||||
| `triage.yml` | PR opened/updated | Labels and a results comment (base-branch code only) |
|
||||
| `generate-readme.yml` | push to main | README.md and dist/registry.json; fails without writing on any invalid entry. The regenerated commit is staged on `bot/readme-*`, validated, then fast-forwarded onto main |
|
||||
| `generate-readme.yml` | push to main | README.md and dist/registry.json; fails without writing on any invalid entry. The regenerated commit goes through a bot PR (`bot/readme-*`) that merges itself once `validate` passes |
|
||||
| `site.yml` | push to main, daily | Search site on GitHub Pages |
|
||||
| `health.yml` | daily | Health report issue, rename and removal PRs |
|
||||
| `reprobe.yml` | daily | Re-checks `needs-v2` PRs |
|
||||
|
||||
Reference in new issue
Block a user