ci(release-sdk): bring CI gates to parity with release.yml (#2929)

Ports the pre-publish CI gates that release.yml applies into release-sdk.yml,
so the stopgap workflow ships releases at the same quality bar as the
canonical workflow (minus the @gsd-build/sdk publish, still intentionally
omitted, and the release-branch ceremony, intentionally omitted).

Changes (all mechanical copies of release.yml patterns):

  - install-smoke as needs: dependency. The reusable workflow at
    .github/workflows/install-smoke.yml runs the cross-platform install
    matrix (Ubuntu 22/24, macOS 24, packed-vs-unpacked). Publish job
    won't start until install-smoke passes for the dispatched ref.

  - npm test → npm run test:coverage. Full coverage gate, matching
    release.yml's pre-publish test step.

  - Tolerant tag-existence check. The previous upfront "refuse if tag
    exists" was too strict — operators re-running after a mid-flight
    publish-step failure would be blocked by the tag they successfully
    pushed last time. New behavior matches release.yml: skip the tag
    step if the tag points at HEAD; error only if it points elsewhere.

  - Tag-and-push step gets the same skip-if-at-HEAD pattern.

  - New "Re-point next dist-tag at the new latest" step, gated on
    tag=latest. Matches release.yml#finalize "Clean up next dist-tag" —
    keeps @next from going stale relative to @latest.

  - New "Create GitHub Release" step. Per-tag flag selection:
      tag=dev, tag=next  → --prerelease (won't be highlighted on repo home)
      tag=latest         → --latest (becomes the highlighted release)
    All use --generate-notes so the release body auto-fills from commits.

  - Summary updated to mention the GitHub Release and dist-tag re-point.

Out of scope per #2929:
  - canary.yml, release.yml unchanged (verified by file diff)
  - bin/install.js unchanged (install path already uses bundled SDK)
  - No @gsd-build/sdk publish anywhere
  - No release/X.Y.Z branch ceremony (this stopgap targets dispatched
    ref directly)
This commit is contained in:
Tom Boucher
2026-04-30 20:59:37 -04:00
parent bdead2ee6a
commit 0e0f6952c5

View File

@@ -18,7 +18,7 @@
# remain the canonical two-package publish path; restore them to primary
# use once @gsd-build/sdk ownership is recovered.
#
# Tracking issue: #2925
# Tracking issues: #2925 (initial workflow), #2929 (CI-gate parity with release.yml)
name: Release SDK Bundle
@@ -57,11 +57,22 @@ env:
NODE_VERSION: 24
jobs:
# Cross-platform install validation gate (parity with release.yml).
# Publish job depends on this — won't proceed if the package fails to
# install cleanly across the supported matrix.
install-smoke:
permissions:
contents: read
uses: ./.github/workflows/install-smoke.yml
with:
ref: ${{ inputs.ref }}
release:
needs: install-smoke
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write # tag + push
contents: write # tag + push + GitHub Release
id-token: write # provenance
environment: npm-publish
steps:
@@ -126,13 +137,22 @@ jobs:
exit 1
fi
- name: Refuse if git tag already exists
# Tolerant tag-existence check (matches release.yml pattern). An
# operator re-running after a mid-flight publish-step failure should
# not be blocked just because the tag step succeeded last time. Only
# error if the existing tag points at a different commit than HEAD.
- name: Check git tag (skip if matches HEAD, error if mismatched)
env:
VERSION: ${{ steps.ver.outputs.version }}
run: |
if git rev-parse "v${VERSION}" >/dev/null 2>&1; then
echo "::error::git tag v${VERSION} already exists. Bump version or pass an explicit override input."
exit 1
if git rev-parse -q --verify "refs/tags/v${VERSION}" >/dev/null; then
EXISTING_SHA=$(git rev-parse "refs/tags/v${VERSION}")
HEAD_SHA=$(git rev-parse HEAD)
if [ "$EXISTING_SHA" != "$HEAD_SHA" ]; then
echo "::error::git tag v${VERSION} already exists pointing at ${EXISTING_SHA}, but HEAD is ${HEAD_SHA}"
exit 1
fi
echo "::notice::tag v${VERSION} already exists at HEAD; tag step will skip"
fi
- name: Configure git identity
@@ -150,8 +170,8 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Run full test suite
run: npm test
- name: Run full test suite with coverage (parity with release.yml)
run: npm run test:coverage
- name: Build SDK dist for tarball
run: npm run build:sdk
@@ -224,7 +244,11 @@ jobs:
env:
VERSION: ${{ steps.ver.outputs.version }}
run: |
git tag "v${VERSION}"
if git rev-parse -q --verify "refs/tags/v${VERSION}" >/dev/null; then
echo "Tag v${VERSION} already exists at HEAD (per pre-flight check); skipping git tag step"
else
git tag "v${VERSION}"
fi
git push origin "v${VERSION}"
- name: Publish to npm (CC bundle, SDK included as both loose tree and .tgz)
@@ -234,6 +258,42 @@ jobs:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --provenance --access public --tag "$TAG"
# Keep `next` from going stale relative to `latest`. When publishing a
# stable release, also point `next` at it so users on `@next` don't
# get stuck on an older pre-release than what's now stable. Parity
# with release.yml#finalize "Clean up next dist-tag" step.
- name: Re-point next dist-tag at the new latest (only when tag=latest)
if: ${{ !inputs.dry_run && steps.ver.outputs.tag == 'latest' }}
env:
VERSION: ${{ steps.ver.outputs.version }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
npm dist-tag add "get-shit-done-cc@${VERSION}" next
echo "✅ next dist-tag re-pointed to v${VERSION} (matches latest)"
- name: Create GitHub Release
if: ${{ !inputs.dry_run }}
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.ver.outputs.version }}
TAG: ${{ steps.ver.outputs.tag }}
run: |
# Per-tag release flags:
# dev, next → --prerelease (won't be highlighted as the latest release on the repo page)
# latest → --latest (becomes the highlighted release)
if [ "$TAG" = "latest" ]; then
gh release create "v${VERSION}" \
--title "v${VERSION}" \
--generate-notes \
--latest
else
gh release create "v${VERSION}" \
--title "v${VERSION}" \
--generate-notes \
--prerelease
fi
echo "✅ GitHub Release v${VERSION} created"
- name: Verify publish landed on registry
if: ${{ !inputs.dry_run }}
env:
@@ -269,12 +329,16 @@ jobs:
echo "## Release SDK Bundle: v${VERSION} → @${TAG}" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
if [ "$DRY_RUN" = "true" ]; then
echo "**DRY RUN** — npm publish, git tag, and push were skipped." >> "$GITHUB_STEP_SUMMARY"
echo "**DRY RUN** — npm publish, git tag, push, and GitHub Release were skipped." >> "$GITHUB_STEP_SUMMARY"
else
echo "- Published \`get-shit-done-cc@${VERSION}\` to dist-tag \`${TAG}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- SDK bundled inside the CC tarball at:" >> "$GITHUB_STEP_SUMMARY"
echo " - \`sdk/dist/cli.js\` (loose tree, consumed by \`bin/gsd-sdk.js\` shim)" >> "$GITHUB_STEP_SUMMARY"
echo " - \`sdk-bundle/gsd-sdk.tgz\` (npm-installable artifact)" >> "$GITHUB_STEP_SUMMARY"
echo "- Git tag \`v${VERSION}\` pushed" >> "$GITHUB_STEP_SUMMARY"
echo "- GitHub Release \`v${VERSION}\` created" >> "$GITHUB_STEP_SUMMARY"
if [ "$TAG" = "latest" ]; then
echo "- \`next\` dist-tag re-pointed at \`v${VERSION}\` (kept current with \`latest\`)" >> "$GITHUB_STEP_SUMMARY"
fi
echo "- Install: \`npm install -g get-shit-done-cc@${TAG}\`" >> "$GITHUB_STEP_SUMMARY"
fi