Skip to content

ci: release from a dispatched workflow and sync the plugin version - #109

Merged
kpal81xd merged 3 commits into
mainfrom
ci/release-workflow
Oct 12, 2026
Merged

kpal81xd merged 3 commits into
mainfrom
ci/release-workflow

Conversation

@kpal81xd

@kpal81xd kpal81xd commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Replaces release.sh and the tag-triggered publish workflow with one manually dispatched Publish workflow that bumps the version, keeps the plugin pin in sync, publishes to npm, then pushes and creates the GitHub release. Stacked on #107.

  • .github/workflows/publish.yml: rewritten in place (same filename) as a workflow_dispatch workflow with a type choice of patch, minor, major, premajor or prerelease. Prereleases use --preid=beta, as release.sh did. It only runs on main in playcanvas, and concurrency: publish stops two releases overlapping.
  • scripts/sync-plugin-version.mjs: writes the root package.json version into plugin/.claude-plugin/plugin.json version, the @x.y.z pin in plugin/.mcp.json, and the same pin in the "What it runs" block of plugin/README.md. --check exits non-zero if any of them differ. It always passes when package.json is on a prerelease, so CI on main stays green after a beta.
  • release.sh: removed.

Version policy

  • Stable releases (patch, minor, major) move the plugin pin in all three places, in the same commit as package.json and package-lock.json.
  • Prereleases (premajor, prerelease) leave plugin/ untouched, so plugin users stay on the last stable version. The beta is published to the beta dist-tag and its GitHub release is marked as a prerelease. This settles the open question in ci: release from a dispatched workflow and keep the plugin version pin in sync #105.

Order of steps

  1. Bump the version, sync the plugin pin (stable only), commit as github-actions[bot] and create an annotated vX.Y.Z tag. Nothing is pushed yet.
  2. Build, run publint, then npm publish --provenance with dist-tag beta for prereleases and latest otherwise.
  3. git push --atomic origin HEAD:main "$TAG".
  4. Create the GitHub release with generated notes.

Release and publish run in one job because a tag pushed with GITHUB_TOKEN doesn't trigger other workflows. Publishing comes before the push, so a failed publish leaves main and the tags as they were, and you can just re-run. Commit and tag messages are the bare version (0.8.0), the same as npm version produced for earlier tags.

Recovery:

  • Push fails after a successful publish (for example, because main moved during the run): the version is on npm but not in the repo. Bump, sync, commit and tag that same version on main by hand, push it, then create the release.
  • Release step fails: create the release from the pushed tag by hand. Re-running the job would try to publish the same version again and fail.

Notes for review

  • Provenance now points at the commit the workflow was dispatched from, not the vX.Y.Z commit, because publishing happens before the release commit is pushed. Under the old tag-triggered flow, the two were the same commit.
  • Not verified: npm trusted publishing. I'm assuming it's configured for this workflow file. The old workflow published with no token, which suggests it is, and keeping the filename publish.yml keeps that configuration matching. I can't see the npm side.
  • main has rulesets for deletion and non-fast-forward only, so the bot push to main should be allowed. A real run is the first proof.

Closes #105

Manual smoke test

  1. After merging to main, open Actions, choose Publish, then Run workflow on main with type patch. Expected: the run succeeds and main gets one github-actions[bot] commit, titled with the new version, that changes package.json, package-lock.json, plugin/.claude-plugin/plugin.json, plugin/.mcp.json and plugin/README.md.
  2. Look at the new tag and release on GitHub. Expected: an annotated vX.Y.Z tag on that commit, and a GitHub release with generated notes that isn't marked as a prerelease.
  3. Open the package on npmjs.com. Expected: the new version is latest and shows a provenance badge linked to the Publish run.
  4. Pull main and start Claude Code with claude --plugin-dir plugin. Expected: /plugin shows playcanvas-editor at the new version, and /mcp connects plugin:playcanvas-editor:playcanvas running the new npm version.
  5. Run Publish again with type prerelease. Expected: a vX.Y.(Z+1)-beta.0 tag and a GitHub release marked as a prerelease. The new version appears on npm under the beta dist-tag, while latest stays on the stable version. The release commit changes only package.json and package-lock.json, and plugin/ still pins the stable version from step 1.
  6. Try to start Publish from any branch other than main. Expected: the job is skipped and nothing is published or pushed.

@kpal81xd
kpal81xd force-pushed the ci/release-workflow branch from c786b4b to 0dfc127 Compare October 12, 2026 14:24
Base automatically changed from feat/claude-plugin to main October 12, 2026 14:46
@kpal81xd kpal81xd closed this Oct 12, 2026
@kpal81xd kpal81xd reopened this Oct 12, 2026
@kpal81xd
kpal81xd merged commit a156932 into main Oct 12, 2026
3 checks passed
@kpal81xd
kpal81xd deleted the ci/release-workflow branch October 12, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: release from a dispatched workflow and keep the plugin version pin in sync

1 participant