feat: automate OpenAPI sync with Bee releases#820
Conversation
Signed-off-by: Yejin Kelly Joo <yejinkellyjoo@gmail.com>
Signed-off-by: Yejin Kelly Joo <yejinkellyjoo@gmail.com>
Signed-off-by: Yejin Kelly Joo <yejinkellyjoo@gmail.com>
- add PULL_REQUEST_TEMPLATE.md with what/details/checklist sections - checklist adapted to this repo's build, link-check, and llms.txt conventions Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Yejin Kelly Joo <yejinkellyjoo@gmail.com>
✅ Deploy Preview for test-twitter-preview-testing-3 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
crtahlin
left a comment
There was a problem hiding this comment.
Approving — solid, well-documented automation that replaces the manual find/replace. The design is sound: stable-only filtering, human-gated version bump, BOT_PAT fail-loud, scoped permissions:, concurrency control, and defense-in-depth re-validation of the tag before pushing. Verified the assumptions against master — the TAG=vX.Y.Z anchor in quick-start.md, all 7 target doc files, and both openapi/*.yaml specs exist. CI build is green.
A couple of should-fix hardening items (non-blocking):
1. update-openapi.yaml — "Resolve latest stable Bee tag" step: route the dispatch input through env: and validate it.
${{ github.event.inputs.tag }} is interpolated directly into the run: shell (both the if [ -n ... ] test and the NEW_TAG= assignment). Two issues:
- Injection: this is the pattern GitHub's hardening guidance warns against. Only
workflow_dispatch-privileged users can reach it, so severity is low — but it's inconsistent with the rest of the PR, which correctly usesenv:everywhere else, and the resultingNEW_VERlater feeds aseddelimiter where a/or&would misbehave. - Validation bypass: the
^v[0-9]+\.[0-9]+\.[0-9]+$stable filter only applies to the auto-detectedgit ls-remotepath. A forced dispatch tag (e.g.v2.9.0-rc1) skips it entirely, contradicting the "prereleases are skipped" guarantee.
One fix closes both: pass via env: INPUT_TAG: ${{ github.event.inputs.tag }}, reference "$INPUT_TAG", and run it through the same regex guard already used in tag-on-openapi-merge.yaml.
2. update-openapi.yaml — pin the third-party action to a SHA.
peter-evans/create-pull-request@v6 runs with contents/pull-requests: write plus BOT_PAT. Consider pinning to a full commit SHA (@<sha> # v6.x) for supply-chain hardening. First-party actions/checkout@v4 is lower risk.
Nit: tag-on-openapi-merge.yaml tags base.ref at current HEAD, so an unrelated commit landing on master between merge and run would shift the tag target — low likelihood given the gating, fine as-is.
Nice touches: the triple-gated if: on the merge workflow, the documented sed-scope reasoning, and dropping the duplicate CLAUDE.md line in .gitignore.
What does this PR resolve? 🚀
Automates keeping the docs in sync with ethersphere/bee releases, replacing the manual copy-and-find/replace process.
.github/workflows/update-openapi.yaml— daily (and manual) job that detects the latest stable Bee tag, pullsopenapi/Swarm.yaml+SwarmCommon.yamlfrom it, bumps Bee version strings in the install docs, and opens/updates a PR labelledopenapi-auto-update..github/workflows/tag-on-openapi-merge.yaml— on merge of that PR, tags the merge commitvX.Y.Z, triggering the existinggh-pages.yamldeploy.README.mdand tracks a newCLAUDE.md(un-ignored from.gitignore).Details 📝
^v[0-9]+\.[0-9]+\.[0-9]+$, so all prereleases (-rc*,-beta,v2.7.1a,v2.5.0-v8) are skipped.git ls-remote(no auth); current docs version read from theTAG=vX.Y.Zanchor inquick-start.md(avoids needing a version source-of-truth and dodges thev4.0.1tag anomaly).sedswap across 7 fixed doc files — deliberately rewrites thevX.Y.Z,bee:X.Y.Z, andX.Y.Z-<hash>forms while leaving the unrelated openapiapiVersion: 7.3.0untouched (verified with av2.7.0dry-run). Best-effort; the PR body flags it for human review.BOT_PATrequired: both workflows need aBOT_PATrepository secret (classic PAT withpublic_repo, or fine-grained with contents + pull-requests write). They fail loudly if it's missing/expired.CLAUDE.mdnow tracked: previously gitignored; un-ignored and committed so contributor/agent guidance ships with the repo.actionlint-checked locally (tool unavailable) — embedded shell wasbash -n-checked and the substitution behavior tested manually.Checklist ✅
masterand resolved conflictsnpm run buildsucceedsnpm run check:links) where relevantstatic/llms.txtupdated if pages were added / renamed / deletedSwarmvsswarm)git commit -s)