Files
get-shit-done/.github/workflows/release.yml
Jeremy McSpadden 0a049149e1 fix(sdk): decouple from build-from-source install, close #2441 #2453 (#2457)
* fix(sdk): decouple SDK from build-from-source install path, close #2441 and #2453

Ship sdk/dist prebuilt in the tarball and replace the npm-install-g
sub-install with a parent-package bin shim (bin/gsd-sdk.js). npm chmods
bin entries from a packed tarball correctly, eliminating the mode-644
failure (#2453) and the full class of NPM_CONFIG_PREFIX/ignore-scripts/
corepack/air-gapped failure modes that caused #2439 and #2441.

Changes:
- sdk/package.json: prepublishOnly runs `rm -rf dist && tsc && chmod +x
  dist/cli.js` (stale-build guard + execute-bit fix at publish time)
- package.json: add "gsd-sdk": "bin/gsd-sdk.js" bin entry; add sdk/dist
  to files so the prebuilt CLI ships in the tarball
- bin/gsd-sdk.js: new back-compat shim — resolves sdk/dist/cli.js relative
  to the package root and delegates via `node`, so all existing PATH call
  sites (slash commands, agents, hooks) continue to work unchanged (S1 shim)
- bin/install.js: replace installSdkIfNeeded() build-from-source + global-
  install dance with a dist-verify + chmod-in-place guard; delete
  resolveGsdSdk(), detectShellRc(), emitSdkFatal() helpers now unused
- .github/workflows/install-smoke.yml: add smoke-unpacked job that strips
  execute bit from sdk/dist/cli.js before install to reproduce the exact
  #2453 failure mode
- tests/bug-2441-sdk-decouple.test.cjs: new regression tests asserting all
  invariants (no npm install -g from sdk/, shim exists, sdk/dist in files,
  prepublishOnly has rm -rf + chmod)
- tests/bugs-1656-1657.test.cjs: update stale assertions that required
  build-from-source behavior (now asserts new prebuilt-dist invariants)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(release): bump to 1.38.2, wire release.yml to build SDK dist

- Bump version 1.38.1 -> 1.38.2 for the #2441/#2453 fix shipped in 0f6903d.
- Add `build:sdk` script (`cd sdk && npm ci && npm run build`).
- `prepublishOnly` now runs hooks + SDK builds as a safety net.
- release.yml (rc + finalize): build SDK dist before `npm publish` so the
  published tarball always ships fresh `sdk/dist/` (kept gitignored).
- CHANGELOG: document 1.38.2 entry and `--sdk` flag semantics change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci: build SDK dist before tests and smoke jobs

sdk/dist/ is gitignored (built fresh at publish time via release.yml),
but both the test suite and install-smoke jobs run `bin/install.js`
or `npm pack` against the checked-out tree where dist doesn't exist yet.

- test.yml: `npm run build:sdk` before `npm run test:coverage`, so tests
  that spawn `bin/install.js` don't hit `installSdkIfNeeded()`'s fatal
  missing-dist check.
- install-smoke.yml (both smoke and smoke-unpacked): build SDK before
  pack/chmod so the published tarball contains dist and the unpacked
  install has a file to strip exec-bit from.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sdk): lift SDK runtime deps to parent so tarball install can resolve them

The SDK's runtime deps (ws, @anthropic-ai/claude-agent-sdk) live in
sdk/package.json, but sdk/node_modules is NOT shipped in the parent
tarball — only sdk/dist, sdk/src, sdk/prompts, and sdk/package.json are.
When a user runs `npm install -g get-shit-done-cc`, npm installs the
parent's node_modules but never runs `npm install` inside the nested
sdk/ directory.

Result: `node sdk/dist/cli.js` fails with ERR_MODULE_NOT_FOUND for 'ws'.
The smoke tarball job caught this; the unpacked variant masked it
because `npm install -g <dir>` copies the entire workspace including
sdk/node_modules (left over from `npm run build:sdk`).

Fix: declare the same deps in the parent package.json so they land in
<pkg>/node_modules, which Node's resolution walks up to from
<pkg>/sdk/dist/cli.js. Keep them declared in sdk/package.json too so
the SDK remains a self-contained package for standalone dev.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(lockfile): regenerate package-lock.json cleanly

The previous `npm install` run left the lockfile internally inconsistent
(resolved esbuild@0.27.7 referenced but not fully written), causing
`npm ci` to fail in CI with "Missing from lock file" errors.

Clean regen via rm + npm install fixes all three failed jobs
(test, smoke, smoke-unpacked), which were all hitting the same
`npm ci` sync check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(deps): remove unused esbuild + vitest from root devDependencies

Both were declared but never imported anywhere in the root package
(confirmed via grep of bin/, scripts/, tests/). They lived in sdk/
already, which is the only place they're actually used.

The transitive tree they pulled in (vitest → vite → esbuild 0.28 →
@esbuild/openharmony-arm64) was the root of the CI npm ci failures:
the openharmony platform package's `optional: true` flag was not being
applied correctly by npm 10 on Linux runners, causing EBADPLATFORM.

After removal: 800+ transitive packages → 155. Lockfile regenerated
cleanly. All 4170 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sdk): pretest:coverage builds sdk; tighten shim test assertions

Add "pretest:coverage": "npm run build:sdk" so npm run test:coverage
works in clean checkouts where sdk/dist/ hasn't been built yet.

Tighten the two loose shim assertions in bug-2441-sdk-decouple.test.cjs:
- forwards-to test now asserts path.resolve() is called with the
  'sdk','dist','cli.js' path segments, not just substring presence
- node-invocation test now asserts spawnSync(process.execPath, [...])
  pattern, ruling out matches in comments or the shebang line

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address PR review — pretest:coverage + tighten shim tests

Review feedback from trek-e on PR 2457:

1. pretest:coverage + pretest hooks now run `npm run build:sdk` so
   `npm run test[:coverage]` in a clean checkout produces the required
   sdk/dist/ artifacts before running the installer-dependent tests.
   CI already does this explicitly; local contributors benefit.

2. Shim tests in bug-2441-sdk-decouple.test.cjs tightened from loose
   substring matches (which would pass on comments/shebangs alone) to
   regex assertions on the actual path.resolve call, spawnSync with
   process.execPath, process.argv.slice(2), and process.exit pattern.
   These now provide real regression protection for #2453-class bugs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: correct CHANGELOG entry and add [1.38.2] reference link

Two issues in the 1.38.2 CHANGELOG entry:
- installSdkIfNeeded() was described as deleted but it still exists in
  bin/install.js (repurposed to verify sdk/dist/cli.js and fix execute bit).
  Corrected the description to say 'repurposes' rather than 'deletes'.
- The reference-link block at the bottom of the file was missing a [1.38.2]
  compare URL and [Unreleased] still pointed to v1.37.1...HEAD. Added the
  [1.38.2] link and updated [Unreleased] to compare/v1.38.2...HEAD.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(sdk): double-cast WorkflowConfig to Record for strict tsc build

TypeScript error on main (introduced in #2611) blocks `npm run build`
in sdk/, which now runs as part of this PR's tarball build path. Apply
the double-cast via `unknown` as the compiler suggests.

Same fix as #2622; can be dropped if that lands first.

* test: remove bug-2598 test obsoleted by SDK decoupling

The bug-2598 test guards the Windows CVE-2024-27980 fix in the old
build-from-source path (npm spawnSync with shell:true + formatSpawnFailure
diagnostics). This PR removes that entire code path — installSdkIfNeeded
no longer spawns npm, it just verifies the prebuilt sdk/dist/cli.js
shipped in the tarball.

The test asserts `installSdkIfNeeded.toString()` contains a
formatSpawnFailure helper. After decoupling, no such helper exists
(nothing to format — there's no spawn). Keeping the test would assert
invariants of the rejected architecture.

The original #2598 defect (silent failure of npm spawn on Windows) is
structurally impossible in the shim path: bin/gsd-sdk.js invokes
`node sdk/dist/cli.js` directly via child_process.spawn with an
explicit argv array. No .cmd wrapper, no shell delegation.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
2026-04-23 08:36:03 -04:00

464 lines
17 KiB
YAML

name: Release
on:
workflow_dispatch:
inputs:
action:
description: 'Action to perform'
required: true
type: choice
options:
- create
- rc
- finalize
version:
description: 'Version (e.g., 1.28.0 or 2.0.0)'
required: true
type: string
dry_run:
description: 'Dry run (skip npm publish, tagging, and push)'
required: false
type: boolean
default: false
concurrency:
group: release-${{ inputs.version }}
cancel-in-progress: false
env:
NODE_VERSION: 24
jobs:
validate-version:
runs-on: ubuntu-latest
timeout-minutes: 2
permissions:
contents: read
outputs:
branch: ${{ steps.validate.outputs.branch }}
is_major: ${{ steps.validate.outputs.is_major }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Validate version format
id: validate
env:
VERSION: ${{ inputs.version }}
run: |
# Must be X.Y.0 (minor or major release, not patch)
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.0$'; then
echo "::error::Version must end in .0 (e.g., 1.28.0 or 2.0.0). Use hotfix workflow for patch releases."
exit 1
fi
BRANCH="release/${VERSION}"
# Detect major (X.0.0)
IS_MAJOR="false"
if echo "$VERSION" | grep -qE '^[0-9]+\.0\.0$'; then
IS_MAJOR="true"
fi
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
echo "is_major=$IS_MAJOR" >> "$GITHUB_OUTPUT"
create:
needs: validate-version
if: inputs.action == 'create'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Check branch doesn't already exist
env:
BRANCH: ${{ needs.validate-version.outputs.branch }}
run: |
if git ls-remote --exit-code origin "refs/heads/$BRANCH" >/dev/null 2>&1; then
echo "::error::Branch $BRANCH already exists. Delete it first or use rc/finalize."
exit 1
fi
- name: Configure git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Create release branch
env:
BRANCH: ${{ needs.validate-version.outputs.branch }}
VERSION: ${{ inputs.version }}
IS_MAJOR: ${{ needs.validate-version.outputs.is_major }}
run: |
git checkout -b "$BRANCH"
npm version "$VERSION" --no-git-tag-version
cd sdk && npm version "$VERSION" --no-git-tag-version && cd ..
git add package.json package-lock.json sdk/package.json
git commit -m "chore: bump version to ${VERSION} for release"
git push origin "$BRANCH"
echo "## Release branch created" >> "$GITHUB_STEP_SUMMARY"
echo "- Branch: \`$BRANCH\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Version: \`$VERSION\`" >> "$GITHUB_STEP_SUMMARY"
if [ "$IS_MAJOR" = "true" ]; then
echo "- Type: **Major** (will start with beta pre-releases)" >> "$GITHUB_STEP_SUMMARY"
else
echo "- Type: **Minor** (will start with RC pre-releases)" >> "$GITHUB_STEP_SUMMARY"
fi
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Next: run this workflow with \`rc\` action to publish a pre-release to \`next\`" >> "$GITHUB_STEP_SUMMARY"
install-smoke-rc:
needs: validate-version
if: inputs.action == 'rc'
permissions:
contents: read
uses: ./.github/workflows/install-smoke.yml
with:
ref: ${{ needs.validate-version.outputs.branch }}
rc:
needs: [validate-version, install-smoke-rc]
if: inputs.action == 'rc'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
id-token: write
environment: npm-publish
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ needs.validate-version.outputs.branch }}
fetch-depth: 0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
cache: 'npm'
- name: Determine pre-release version
id: prerelease
env:
VERSION: ${{ inputs.version }}
IS_MAJOR: ${{ needs.validate-version.outputs.is_major }}
run: |
# Determine pre-release type: major → beta, minor → rc
if [ "$IS_MAJOR" = "true" ]; then
PREFIX="beta"
else
PREFIX="rc"
fi
# Find next pre-release number by checking existing tags
N=1
while git tag -l "v${VERSION}-${PREFIX}.${N}" | grep -q .; do
N=$((N + 1))
done
PRE_VERSION="${VERSION}-${PREFIX}.${N}"
echo "pre_version=$PRE_VERSION" >> "$GITHUB_OUTPUT"
echo "prefix=$PREFIX" >> "$GITHUB_OUTPUT"
- name: Configure git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Bump to pre-release version
env:
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
run: |
npm version "$PRE_VERSION" --no-git-tag-version
cd sdk && npm version "$PRE_VERSION" --no-git-tag-version && cd ..
- name: Install and test
run: |
npm ci
npm run test:coverage
- name: Commit pre-release version bump
env:
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
run: |
git add package.json package-lock.json sdk/package.json
git commit -m "chore: bump to ${PRE_VERSION}"
- name: Build SDK dist for tarball
run: npm run build:sdk
- name: Dry-run publish validation
run: |
npm publish --dry-run --tag next
cd sdk && npm publish --dry-run --tag next
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Tag and push
if: ${{ !inputs.dry_run }}
env:
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
BRANCH: ${{ needs.validate-version.outputs.branch }}
run: |
if git rev-parse -q --verify "refs/tags/v${PRE_VERSION}" >/dev/null; then
EXISTING_SHA=$(git rev-parse "refs/tags/v${PRE_VERSION}")
HEAD_SHA=$(git rev-parse HEAD)
if [ "$EXISTING_SHA" != "$HEAD_SHA" ]; then
echo "::error::Tag v${PRE_VERSION} already exists pointing to different commit"
exit 1
fi
echo "Tag v${PRE_VERSION} already exists on current commit; skipping tag"
else
git tag "v${PRE_VERSION}"
fi
git push origin "$BRANCH" --tags
- name: Publish to npm (next)
if: ${{ !inputs.dry_run }}
run: npm publish --provenance --access public --tag next
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish SDK to npm (next)
if: ${{ !inputs.dry_run }}
run: cd sdk && npm publish --provenance --access public --tag next
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub pre-release
if: ${{ !inputs.dry_run }}
env:
GH_TOKEN: ${{ github.token }}
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
run: |
gh release create "v${PRE_VERSION}" \
--title "v${PRE_VERSION}" \
--generate-notes \
--prerelease
- name: Verify publish
if: ${{ !inputs.dry_run }}
env:
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
run: |
sleep 10
PUBLISHED=$(npm view get-shit-done-cc@"$PRE_VERSION" version 2>/dev/null || echo "NOT_FOUND")
if [ "$PUBLISHED" != "$PRE_VERSION" ]; then
echo "::error::Published version verification failed. Expected $PRE_VERSION, got $PUBLISHED"
exit 1
fi
echo "✓ Verified: get-shit-done-cc@$PRE_VERSION is live on npm"
SDK_PUBLISHED=$(npm view @gsd-build/sdk@"$PRE_VERSION" version 2>/dev/null || echo "NOT_FOUND")
if [ "$SDK_PUBLISHED" != "$PRE_VERSION" ]; then
echo "::error::SDK version verification failed. Expected $PRE_VERSION, got $SDK_PUBLISHED"
exit 1
fi
echo "✓ Verified: @gsd-build/sdk@$PRE_VERSION is live on npm"
# Also verify dist-tag
NEXT_TAG=$(npm dist-tag ls get-shit-done-cc 2>/dev/null | grep "next:" | awk '{print $2}')
echo "✓ next tag points to: $NEXT_TAG"
- name: Summary
env:
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
DRY_RUN: ${{ inputs.dry_run }}
run: |
echo "## Pre-release v${PRE_VERSION}" >> "$GITHUB_STEP_SUMMARY"
if [ "$DRY_RUN" = "true" ]; then
echo "**DRY RUN** — npm publish, tagging, and push skipped" >> "$GITHUB_STEP_SUMMARY"
else
echo "- Published to npm as \`next\`" >> "$GITHUB_STEP_SUMMARY"
echo "- SDK also published: \`@gsd-build/sdk@${PRE_VERSION}\` on \`next\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Install: \`npx get-shit-done-cc@next\`" >> "$GITHUB_STEP_SUMMARY"
fi
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "To publish another pre-release: run \`rc\` again" >> "$GITHUB_STEP_SUMMARY"
echo "To finalize: run \`finalize\` action" >> "$GITHUB_STEP_SUMMARY"
install-smoke-finalize:
needs: validate-version
if: inputs.action == 'finalize'
permissions:
contents: read
uses: ./.github/workflows/install-smoke.yml
with:
ref: ${{ needs.validate-version.outputs.branch }}
finalize:
needs: [validate-version, install-smoke-finalize]
if: inputs.action == 'finalize'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
pull-requests: write
id-token: write
environment: npm-publish
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ needs.validate-version.outputs.branch }}
fetch-depth: 0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
cache: 'npm'
- name: Configure git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Set final version
env:
VERSION: ${{ inputs.version }}
run: |
npm version "$VERSION" --no-git-tag-version --allow-same-version
cd sdk && npm version "$VERSION" --no-git-tag-version --allow-same-version && cd ..
git add package.json package-lock.json sdk/package.json
git diff --cached --quiet || git commit -m "chore: finalize v${VERSION}"
- name: Install and test
run: |
npm ci
npm run test:coverage
- name: Build SDK dist for tarball
run: npm run build:sdk
- name: Dry-run publish validation
run: |
npm publish --dry-run
cd sdk && npm publish --dry-run
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create PR to merge release back to main
if: ${{ !inputs.dry_run }}
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
BRANCH: ${{ needs.validate-version.outputs.branch }}
VERSION: ${{ inputs.version }}
run: |
# Non-fatal: repos that disable "Allow GitHub Actions to create and
# approve pull requests" cause this step to fail with GraphQL 403.
# The release itself (tag + npm publish + GitHub Release) must still
# proceed. Open the merge-back PR manually afterwards with:
# gh pr create --base main --head release/${VERSION} \
# --title "chore: merge release v${VERSION} to main"
EXISTING_PR=$(gh pr list --base main --head "$BRANCH" --state open --json number --jq '.[0].number' 2>/dev/null || echo "")
if [ -n "$EXISTING_PR" ]; then
echo "PR #$EXISTING_PR already exists; updating"
gh pr edit "$EXISTING_PR" \
--title "chore: merge release v${VERSION} to main" \
--body "Merge release branch back to main after v${VERSION} stable release." \
|| echo "::warning::Could not update merge-back PR (likely PR-creation policy disabled). Open it manually after release."
else
gh pr create \
--base main \
--head "$BRANCH" \
--title "chore: merge release v${VERSION} to main" \
--body "Merge release branch back to main after v${VERSION} stable release." \
|| echo "::warning::Could not create merge-back PR (likely PR-creation policy disabled). Open it manually after release."
fi
- name: Tag and push
if: ${{ !inputs.dry_run }}
env:
VERSION: ${{ inputs.version }}
BRANCH: ${{ needs.validate-version.outputs.branch }}
run: |
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::Tag v${VERSION} already exists pointing to different commit"
exit 1
fi
echo "Tag v${VERSION} already exists on current commit; skipping tag"
else
git tag "v${VERSION}"
fi
git push origin "$BRANCH" --tags
- name: Publish to npm (latest)
if: ${{ !inputs.dry_run }}
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish SDK to npm (latest)
if: ${{ !inputs.dry_run }}
run: cd sdk && npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub Release
if: ${{ !inputs.dry_run }}
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ inputs.version }}
run: |
gh release create "v${VERSION}" \
--title "v${VERSION}" \
--generate-notes \
--latest
- name: Clean up next dist-tag
if: ${{ !inputs.dry_run }}
env:
VERSION: ${{ inputs.version }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
# Point next to the stable release so @next never returns something
# older than @latest. This prevents stale pre-release installs.
npm dist-tag add "get-shit-done-cc@${VERSION}" next 2>/dev/null || true
npm dist-tag add "@gsd-build/sdk@${VERSION}" next 2>/dev/null || true
echo "✓ next dist-tag updated to v${VERSION}"
- name: Verify publish
if: ${{ !inputs.dry_run }}
env:
VERSION: ${{ inputs.version }}
run: |
sleep 10
PUBLISHED=$(npm view get-shit-done-cc@"$VERSION" version 2>/dev/null || echo "NOT_FOUND")
if [ "$PUBLISHED" != "$VERSION" ]; then
echo "::error::Published version verification failed. Expected $VERSION, got $PUBLISHED"
exit 1
fi
echo "✓ Verified: get-shit-done-cc@$VERSION is live on npm"
SDK_PUBLISHED=$(npm view @gsd-build/sdk@"$VERSION" version 2>/dev/null || echo "NOT_FOUND")
if [ "$SDK_PUBLISHED" != "$VERSION" ]; then
echo "::error::SDK version verification failed. Expected $VERSION, got $SDK_PUBLISHED"
exit 1
fi
echo "✓ Verified: @gsd-build/sdk@$VERSION is live on npm"
# Verify latest tag
LATEST_TAG=$(npm dist-tag ls get-shit-done-cc 2>/dev/null | grep "latest:" | awk '{print $2}')
echo "✓ latest tag points to: $LATEST_TAG"
- name: Summary
env:
VERSION: ${{ inputs.version }}
DRY_RUN: ${{ inputs.dry_run }}
run: |
echo "## Release v${VERSION}" >> "$GITHUB_STEP_SUMMARY"
if [ "$DRY_RUN" = "true" ]; then
echo "**DRY RUN** — npm publish, tagging, and push skipped" >> "$GITHUB_STEP_SUMMARY"
else
echo "- Published to npm as \`latest\`" >> "$GITHUB_STEP_SUMMARY"
echo "- SDK also published: \`@gsd-build/sdk@${VERSION}\` as \`latest\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Tagged \`v${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- PR created to merge back to main" >> "$GITHUB_STEP_SUMMARY"
echo "- Install: \`npx get-shit-done-cc@latest\`" >> "$GITHUB_STEP_SUMMARY"
fi