ci(provenance): auto-create v<version> tag after socket publish#1322
ci(provenance): auto-create v<version> tag after socket publish#1322John-David Dalton (jdalton) wants to merge 1 commit into
Conversation
Adds a Tag release step at the end of the build job, idempotently tagging the published commit SHA with v<version> after the `socket` npm package publishes successfully. Gated on `steps.publish_socket.outcome == 'success'` (the other two publishes — `@socketsecurity/cli`, `cli-with-sentry` — don't drive the v<version> tag). Hard-fails on SHA mismatch with an existing tag rather than silently moving it — GitHub Release Immutability freezes tags bound to a Release, so a wrong tag requires manual recovery. Bumps job permissions to `contents: write` and the checkout's `persist-credentials` to `true` so the tag can be pushed. Why: socket-cli 1.1.98 and 1.1.99 were published from this branch with no git tags on origin (had to be hand-created on 2026-05-20 from npm view gitHead). Mirrors the same patch landed on main, adapted to v1.x's single-job standalone workflow.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: 404 response body breaks tag existence check
- Split the command substitution from the fallback (
$(gh api ...) || EXISTING_JSON="") so that on a 404 the variable is explicitly overwritten to empty, preventing the non-empty check from passing with the error JSON body.
- Split the command substitution from the fallback (
Or push these changes by commenting:
@cursor push bad849d7f8
Preview (bad849d7f8)
diff --git a/.github/workflows/provenance.yml b/.github/workflows/provenance.yml
--- a/.github/workflows/provenance.yml
+++ b/.github/workflows/provenance.yml
@@ -258,7 +258,7 @@
TAG="v$PUBLISHED_VERSION"
# Look up any existing tag via the API. 200 → exists; 404 → absent.
- EXISTING_JSON=$(gh api "repos/$REPO/git/ref/tags/$TAG" 2>/dev/null || echo "")
+ EXISTING_JSON=$(gh api "repos/$REPO/git/ref/tags/$TAG" 2>/dev/null) || EXISTING_JSON=""
if [ -n "$EXISTING_JSON" ]; then
EXISTING_SHA=$(echo "$EXISTING_JSON" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).object.sha")
if [ "$EXISTING_SHA" = "$PUBLISHED_SHA" ]; thenYou can send follow-ups to the cloud agent here.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 7e12956. Configure here.
|
|
||
| # Look up any existing tag via the API. 200 → exists; 404 → absent. | ||
| EXISTING_JSON=$(gh api "repos/$REPO/git/ref/tags/$TAG" 2>/dev/null || echo "") | ||
| if [ -n "$EXISTING_JSON" ]; then |
There was a problem hiding this comment.
404 response body breaks tag existence check
High Severity
gh api outputs the 404 JSON response body ({"message":"Not Found",…}) to stdout even on failure. The 2>/dev/null only suppresses stderr, and in bash $(cmd1 || cmd2), stdout from the failed cmd1 is still captured. So when a tag does not exist, EXISTING_JSON contains the error JSON (non-empty), causing [ -n "$EXISTING_JSON" ] to be true. The subsequent node -p then tries to access .object.sha on the error object, which throws a TypeError and fails the step under set -e. Tags can never be created for new versions — the primary purpose of this change.
Reviewed by Cursor Bugbot for commit 7e12956. Configure here.
| EXISTING_JSON=$(gh api "repos/$REPO/git/ref/tags/$TAG" 2>/dev/null || echo "") | ||
| if [ -n "$EXISTING_JSON" ]; then | ||
| EXISTING_SHA=$(echo "$EXISTING_JSON" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).object.sha") | ||
| if [ "$EXISTING_SHA" = "$PUBLISHED_SHA" ]; then |
There was a problem hiding this comment.
Annotated tags cause false SHA mismatch failure
Medium Severity
For annotated (signed) tags, the GitHub git/ref/tags API returns the tag object SHA in object.sha, not the commit SHA. Comparing this against PUBLISHED_SHA (a commit SHA from git rev-parse HEAD) will always mismatch, causing a hard-fail even when the tag points to the correct commit. The PR description notes that previous tags were hand-created with git tag -s (which creates annotated tags), so a re-run against those versions would incorrectly trigger the "requires manual recovery" error path.
Reviewed by Cursor Bugbot for commit 7e12956. Configure here.



Summary
Tag release (idempotent)step at the end of the v1.x publish workflow to auto-createv<version>git tags after a successfulsocketnpm publish.gh api(notgit push) so theGITHUB_TOKENonly lives in the tag step'senvblock — never written to.git/configwherepnpm installpostinstall scripts could read it.steps.publish_socket.outcome == 'success': the other two publishes (@socketsecurity/cli,cli-with-sentry) usecontinue-on-error: trueand don't represent thev<version>tag.Mirrors the patch landed on
main(8043cf7) andsocket-registry/provenance.yml. Inlined here rather than reusingsocket-registry/.github/workflows/provenance.ymlbecause v1.x is intentionally decoupled from the reusable workflow's evolution.Test plan
options:warning on thedebuginput, unrelated).inputs.sockettrue creates av<cli_version>tag pointing at the published SHA.Why
socket-cli
1.1.98and1.1.99were published from this branch with no git tags on origin — had to be hand-created on 2026-05-20 by readingnpm view socket@<v> gitHeadandgit tag -s vX.Y.Z <sha>. Two published versions in a row with missing tags is a fleet-wide failure mode; the publish path needs to enforce tag creation, not rely on operator memory.Note
Medium Risk
Moderate risk because it changes CI publish permissions and adds automated tag creation; mistakes could create/lock incorrect tags or fail the release pipeline under GitHub Release immutability.
Overview
After a successful
socketnpm publish, the provenance workflow now creates an idempotentv<version>git tag pointing at the published commit SHA (no-op if already correct; hard-fail if the tag exists at a different SHA).To support this, the job permission
contentsis raised towrite, and the first publish step is given anid(publish_socket) so the tag step can be gated on its success while the other publishes remaincontinue-on-error.Reviewed by Cursor Bugbot for commit 7e12956. Configure here.