[PIGS-835] PR-based release workflow#94
Conversation
main is protected from direct push, so the old publish workflow's "git push origin main" no longer works. Split the release into two phases that need only the built-in GITHUB_TOKEN: - release-pr.yml (dispatch): bumps manifest.json and opens a release PR - publish.yml (push to main touching manifest.json): builds the .mcpb, tags the merge commit, and creates the GitHub release Auto-merge is deliberately not used: enabling it with GITHUB_TOKEN attributes the merge to github-actions[bot], whose events do not trigger workflows, so publish.yml would never run. A human approval is required by branch protection anyway; the approver merges manually. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the repository’s release process to work with protected main by switching to a PR-based release workflow: one workflow opens a version-bump PR, and a second workflow publishes the release only after that PR is merged to main.
Changes:
- Add a new Open Release PR workflow that bumps
node-version/manifest.jsonon arelease/vX.Y.Zbranch and opens/updates a PR tomain. - Rewrite Publish Release to trigger on
mainchanges tonode-version/manifest.json, build the.mcpb, tag the merge commit, and create the GitHub release. - Rename the root Taskfile entry point from
publishtorelease, and document the new flow in the README.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| Taskfile.yml | Renames the local task to dispatch the new PR-opening workflow instead of the old publish workflow. |
| README.md | Documents the PR-based release flow for maintainers. |
| .github/workflows/release-pr.yml | New workflow to compute a version, bump manifest, push a release branch, and open/update a release PR. |
| .github/workflows/publish.yml | Publishes releases on merge by building artifacts, tagging the merge commit, and creating the GitHub release. |
| VERSION="${{ steps.version.outputs.value }}" | ||
| if gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/v${VERSION}" --silent 2>/dev/null; then | ||
| echo "Tag v${VERSION} already exists; nothing to publish." | ||
| echo "proceed=false" >> "$GITHUB_OUTPUT" | ||
| else |
There was a problem hiding this comment.
Fixed in 3413236 — the guard now checks gh release view so a rerun recovers a missing release even when the tag already exists.
| git checkout -b "$BRANCH" | ||
| git add node-version/manifest.json | ||
| git commit -m "Release v${VERSION}" | ||
| git push --force origin "$BRANCH" |
There was a problem hiding this comment.
Declining this one: the workflow runs in a fresh shallow checkout with no remote-tracking ref for the release branch, so --force-with-lease would reject the push whenever the branch already exists — exactly the rerun case the force push is there for. Release branches are workflow-owned and short-lived; added a comment in the workflow explaining this (3413236).
| 2. Have a teammate approve the release PR, then merge it. | ||
| - CI does not run on this PR — it is created by a workflow and only changes the version field. | ||
| 3. That's it — on merge, the **Publish Release** workflow runs automatically. It builds the `.mcpb` from the merged commit, tags it `vX.Y.Z`, and publishes the [GitHub release](https://github.com/Nitro/platform-mcp-server/releases). | ||
| - If publishing needs a re-run, dispatch **Publish Release** manually from the Actions tab. It is safe to re-run: versions that are already tagged are skipped. |
There was a problem hiding this comment.
Fixed in 3413236 — README now describes release-based skipping and the partial-failure recovery.
Addresses Copilot review: a rerun can now recover from a partial failure where the tag was created but the release was not. Also documents why the release branch push uses plain --force. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
||
| jobs: | ||
| publish: | ||
| check: |
There was a problem hiding this comment.
Not sure what's the default for permissions if unspecified, but maybe worth explicitly declaring contents: read for check.. for least-privilege parity with the publish job's contents: write.
There was a problem hiding this comment.
Good call — added an explicit contents: read to the check job. (Without it the job inherits the workflow/repo default, which can be broader.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why
Since the repo went public,
mainis protected from direct push, so the old publish workflow'sgit push origin mainstep fails. The previous release (0.21.0) required temporarily disabling branch protection. See PIGS-835.What
The release is now split into two workflows, and both need only the built-in
GITHUB_TOKEN— no nitro-robot PAT and no self-hosted runners.release-pr.yml(new): manually dispatched. It resolves the version, bumps it innode-version/manifest.json, pushes arelease/vX.Y.Zbranch, and opens a release PR againstmain. It fails early if the version is already tagged, and re-running it safely updates the existing release PR instead of failing.publish.yml(rewritten): runs when a change tonode-version/manifest.jsonlands onmain, i.e. when a release PR merges. It builds the.mcpbfrom the merged commit, tags that commit, and creates the GitHub release. It skips itself if the version in the manifest is already tagged, and it can also be dispatched manually as a fallback.Taskfile.yml: thepublishtask used to dispatch the old publish workflow directly. Since the entry point is now the release-PR workflow, the task is renamed toreleaseand dispatchesrelease-pr.yml. Usage:task release(auto-increments the minor version) ortask release -- 1.2.3(explicit version).Release flow
task releaselocally..mcpbattached.Why not auto-merge (as suggested in the ticket)
GitHub does not trigger workflows for events caused by the built-in
GITHUB_TOKEN. If auto-merge were enabled with that token, the eventual merge would be attributed togithub-actions[bot], andpublish.ymlwould silently never run — no tag, no release. Since branch protection requires a human approval regardless, having the approver click merge costs one extra click and keeps everything working without new secrets. If Systems later provides a PAT or GitHub App token, auto-merge can be layered on top.Known limitation: CI does not run on the automated release PR, for the same
GITHUB_TOKENreason. This is low risk because the PR only changes the version field, and the release build happens after the merge inpublish.yml.🤖 Generated with Claude Code