AX-1735: Add tag/release mechanism - #30
Merged
Merged
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tep comments Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Releases landed on main after this branch was cut, bumping plugin.json and marketplace.json to 0.5.6. The validate-version CI check runs against the merge commit and fails when VERSION (0.5.4) doesn't match the JSON files (0.5.6). Bring VERSION and both manifests in line with current main so the merge commit is fully consistent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…SION Resolves the marketplace.json and plugin.json conflicts by taking main's side wholesale. The only thing this branch wanted from those files was a version bump to 0.5.6, which main has since passed (0.5.11), and main also reworded the description and dropped the explicit skills array. Drops the VERSION file: plugin.json already carries the version, so VERSION was a third copy. plugin.json is now canonical and validate-version.yml cross-checks marketplace.json against it instead of both against VERSION. release.yml reads plugin.json, re-checks the two manifests agree before tagging, refuses to re-tag a version that already shipped, and reads the commit message from env rather than interpolating it into the script.
These repos squash-merge, and GitHub pre-fills the squash message body from the branch's commit messages (or the PR description). Both of those quote [major]/[minor]/[patch] while only documenting the flow, so matching the whole message meant merging this very PR would have cut a release nobody asked for. Matching the subject line alone keeps the trigger deliberate: a release happens when someone writes the marker in the subject they are merging, not when a marker happens to appear in generated body text.
… release Three fixes from review, all in release.yml. An orphan tag was possible: the tag was pushed in its own step before `gh release create`, so a failure in between left a tag with no release behind it. The re-run then hit the "already exists" check with nothing actually wrong but the tag, and it needed deleting by hand. The tag is now created by `gh release create --target "$GITHUB_SHA"` in the same API call as the release, so there is no window between the two. Nothing pushes over git anymore, so the write token is gone from the checkout step. Releases were not gated on validation. The validate workflow triggers on the same push, but as a separate workflow with no relationship to this one, so it could still be red while a release went out. The same check now runs here, before the release is created. `zip -r release.zip .` packed the working tree, so anything an earlier step left on the runner would ship inside the artifact. Replaced with `git archive`, which exports tracked files at HEAD, still excluding .github.
…TRIBUTING Review feedback: the per-step comments in release.yml had grown into several paragraphs of rationale, which is documentation rather than a code comment. Each step now carries at most two lines - what it does, or the one constraint a reader could otherwise undo by "simplifying" it: subject-line matching, env rather than interpolation, git archive rather than the working tree, --target creating the tag. A pointer at the top of the file sends readers to CONTRIBUTING.md for the full flow. CONTRIBUTING.md gains the parts the comments had that it did not already say: what the workflow does in order, what ends up in the release zip, why validation runs inside the release job instead of relying on the separate validate workflow, and why the tag is created by the release rather than pushed before it. No behaviour change - the release.yml diff is comments only.
yanivt-jfrog
requested changes
Aug 6, 2026
validate-template.yml and validate-version.yml both trigger on pull_request only, so neither one runs on the merge push. The comment and the CONTRIBUTING note claimed validate-template.yml runs on that push as an independent workflow, which was the wrong reason for a correct conclusion: the real reason is that nothing validates the merge commit unless the release job does it. Also note validate-version.yml, which is gated inline the same way, and keep the independent-workflow caveat as a forward-looking warning rather than a claim about how the workflows trigger today.
yanivt-jfrog
approved these changes
Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a tag/release mechanism, with
plugins/jfrog/.cursor-plugin/plugin.jsonas the canonical version.release.yml— on push tomain, if the commit subject carries[major],[minor]or[patch], reads the version fromplugin.json, confirmsmarketplace.jsonagrees, tagsvX.Y.Z, and publishes a GitHub Release with a repo zip attached.validate-version.yml— PR check that.cursor-plugin/marketplace.json.metadata.versionmatchesplugin.json.VERSIONfile.plugin.jsonalready carries the version, so aVERSIONfile would be a third copy.CONTRIBUTING.mdgains a Releasing section.Notes for reviewers
Why a drift check survives here. This repo genuinely has two manifests: the plugin's own
plugin.jsonand themarketplace.jsonthat Cursor's marketplace reads. The check compares manifest to manifest, withplugin.jsoncanonical — rather than comparing both against a third file that exists only to be compared against.The version comes from the manifest, not from the marker. The marker only decides whether to release; it does not compute a bump. The version change stays reviewable in the PR that makes it, and no bot ever pushes to
main.The marker is matched on the subject line only. This repo squash-merges with the PR description as the default squash body, and that description documents
[minor]. Matching the whole message would have meant merging this very PR cut a release nobody asked for.Merging a marker without bumping the manifests fails the release rather than re-tagging a version that already shipped.
The commit message is read through
env, not interpolated into the script, so a crafted commit subject cannot inject shell.Conflict resolution
This branch had conflicted with
mainsince mid-July. Both conflicts were in files it only wanted a version bump in, andmainhad moved past it on every count:0.5.6→0.5.11, a reworded plugin description, and removal of the explicitskillsarray. Resolved by takingmain's side wholesale, so the net diff is now only the two workflows andCONTRIBUTING.md.Test plan
validate-versionandValidate marketplace templatepass on this PR (both manifests at0.5.11)validate-versionwith a clear error[patch]in the subject, produces the matching tag and GitHub ReleaseCloses AX-1735 / part of AX-1733