Merge pull request #5345 from cardstack/cs-11636-unified-search-drop-… #55
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
| name: boxel-cli publish | |
| # Single workflow file that owns both publish paths for @cardstack/boxel-cli: | |
| # | |
| # • `unstable` job | |
| # - On push to main touching `packages/boxel-cli/**` — regenerate plugin | |
| # skill content, decide per-surface version bumps from the merged PR's | |
| # title (conventional-commit prefix), commit the bumps back to main, | |
| # tag, and publish `@cardstack/boxel-cli@<v>-unstable.<n>` under | |
| # dist-tag `unstable`. | |
| # - Via "Run workflow" with the `confirm` field left blank — skip the | |
| # PR-driven bump/commit/tag dance, derive the next free | |
| # `<base>-unstable.<n>` from npm (npm is the source of truth; the bump | |
| # is not committed back to main), and publish it under dist-tag | |
| # `unstable`. Resolving the counter from npm keeps the manual path from | |
| # clobbering an existing version or colliding with the push path. | |
| # | |
| # • `stable` job — "Run workflow" with `confirm = promote`. Strips | |
| # `-unstable.<n>` from the current version and publishes the resulting | |
| # clean semver under dist-tag `latest`. The deliberate "cut a release" step. | |
| # | |
| # Both flows live in one file so they share a single npm Trusted-Publisher rule | |
| # (registered against this filename). Splitting them into separate workflow files | |
| # would require a second trusted-publisher rule on npmjs.com. | |
| # | |
| # Loop safety (unstable job): | |
| # - Bot commits end with [skip ci] so GitHub does not re-trigger workflows. | |
| # - The job guards with `if: github.actor != 'github-actions[bot]'` (belt + suspenders). | |
| # | |
| # Concurrency: | |
| # - `group: boxel-cli-release, cancel-in-progress: false` serializes back-to-back | |
| # merges and any concurrent manual promotion so prerelease counters and stable | |
| # tags can't race. | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "packages/boxel-cli/**" | |
| workflow_dispatch: | |
| inputs: | |
| confirm: | |
| description: "Leave blank to publish current main as unstable. Type 'promote' to strip -unstable.N and publish as latest." | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| id-token: write | |
| pull-requests: read | |
| concurrency: | |
| group: boxel-cli-release | |
| cancel-in-progress: false | |
| jobs: | |
| unstable: | |
| name: Publish unstable | |
| # Manual trigger is restricted to "Use workflow from: main" so the workflow | |
| # YAML interpreting the publish is always main's (defense in depth — the | |
| # checkout step below also pins `ref: main`). | |
| if: >- | |
| github.actor != 'github-actions[bot]' | |
| && ( | |
| github.event_name == 'push' | |
| || (inputs.confirm == '' && github.ref == 'refs/heads/main') | |
| ) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: main | |
| fetch-depth: 0 | |
| # Need fetch-tags so the script can read boxel-cli-v* tags. | |
| fetch-tags: true | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: ./.github/actions/init | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| - name: Fetch PR title from merge SHA | |
| id: pr | |
| if: github.event_name == 'push' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| PR_JSON=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" --jq '.[0] // empty') | |
| if [ -z "$PR_JSON" ]; then | |
| echo "No PR associated with ${{ github.sha }} — likely a direct push. Skipping." | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| PR_TITLE=$(echo "$PR_JSON" | jq -r '.title') | |
| PR_BODY=$(echo "$PR_JSON" | jq -r '.body // ""') | |
| # Multiline-safe output via heredoc delimiter (GitHub Actions docs). | |
| { | |
| echo "title<<__PR_EOF__" | |
| echo "$PR_TITLE" | |
| echo "__PR_EOF__" | |
| echo "body<<__PR_EOF__" | |
| echo "$PR_BODY" | |
| echo "__PR_EOF__" | |
| } >> "$GITHUB_OUTPUT" | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| echo "PR title: $PR_TITLE" | |
| - name: Regenerate plugin synopsis and skills | |
| if: github.event_name == 'push' && steps.pr.outputs.skip != 'true' | |
| working-directory: packages/boxel-cli | |
| run: | | |
| pnpm run build:plugin | |
| pnpm run build:skills | |
| - name: Compute release | |
| id: release | |
| if: github.event_name == 'push' && steps.pr.outputs.skip != 'true' | |
| working-directory: packages/boxel-cli | |
| env: | |
| PR_TITLE: ${{ steps.pr.outputs.title }} | |
| PR_BODY: ${{ steps.pr.outputs.body }} | |
| run: | | |
| set -euo pipefail | |
| RESULT=$(NODE_NO_WARNINGS=1 pnpm exec node scripts/compute-release.ts) | |
| echo "Compute result: $RESULT" | |
| { | |
| echo "json<<__REL_EOF__" | |
| echo "$RESULT" | |
| echo "__REL_EOF__" | |
| } >> "$GITHUB_OUTPUT" | |
| echo "npmBump=$(echo "$RESULT" | jq -r '.npmBump')" >> "$GITHUB_OUTPUT" | |
| echo "pluginBump=$(echo "$RESULT" | jq -r '.pluginBump')" >> "$GITHUB_OUTPUT" | |
| echo "nextNpm=$(echo "$RESULT" | jq -r '.nextNpm // ""')" >> "$GITHUB_OUTPUT" | |
| echo "nextPlugin=$(echo "$RESULT" | jq -r '.nextPlugin // ""')" >> "$GITHUB_OUTPUT" | |
| - name: Apply version bumps | |
| if: github.event_name == 'push' && steps.pr.outputs.skip != 'true' && (steps.release.outputs.npmBump != 'none' || steps.release.outputs.pluginBump != 'none') | |
| env: | |
| NEXT_NPM: ${{ steps.release.outputs.nextNpm }} | |
| NEXT_PLUGIN: ${{ steps.release.outputs.nextPlugin }} | |
| run: | | |
| set -euo pipefail | |
| if [ -n "$NEXT_NPM" ]; then | |
| node -e ' | |
| const fs = require("fs"); | |
| const p = "packages/boxel-cli/package.json"; | |
| const j = JSON.parse(fs.readFileSync(p, "utf8")); | |
| j.version = process.env.NEXT_NPM; | |
| fs.writeFileSync(p, JSON.stringify(j, null, 2) + "\n"); | |
| ' | |
| echo "package.json → $NEXT_NPM" | |
| fi | |
| if [ -n "$NEXT_PLUGIN" ]; then | |
| node -e ' | |
| const fs = require("fs"); | |
| const p = "packages/boxel-cli/plugin/.claude-plugin/plugin.json"; | |
| const j = JSON.parse(fs.readFileSync(p, "utf8")); | |
| j.version = process.env.NEXT_PLUGIN; | |
| fs.writeFileSync(p, JSON.stringify(j, null, 2) + "\n"); | |
| ' | |
| echo "plugin.json → $NEXT_PLUGIN" | |
| fi | |
| - name: Generate release notes | |
| id: notes | |
| if: github.event_name == 'push' && steps.pr.outputs.skip != 'true' && steps.release.outputs.npmBump != 'none' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| NEW_TAG: boxel-cli-v${{ steps.release.outputs.nextNpm }} | |
| NEXT_NPM: ${{ steps.release.outputs.nextNpm }} | |
| NEXT_PLUGIN: ${{ steps.release.outputs.nextPlugin }} | |
| NPM_DIST_TAG: unstable | |
| REPO: ${{ github.repository }} | |
| RUNNER_TEMP_DIR: ${{ runner.temp }} | |
| run: | | |
| set -euo pipefail | |
| # PREV_TAG is the prior boxel-cli-v* tag reachable from HEAD. Tags | |
| # from earlier publishes point at the previous bot commit, which is | |
| # HEAD's parent at this point in the run (we haven't committed yet). | |
| # Use HEAD as the starting ref; git describe walks back to the | |
| # nearest matching tag automatically. | |
| if PREV_TAG=$(git describe --tags --abbrev=0 --match 'boxel-cli-v*' HEAD 2>/dev/null); then | |
| echo "Previous tag: $PREV_TAG" | |
| else | |
| echo "No prior boxel-cli-v* tag found (bootstrap). Falling back to one-line release body." | |
| echo "has=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| BODY_FILE="$RUNNER_TEMP_DIR/release-body.md" | |
| # The script writes both a body file and a changelog fragment file. | |
| # We only consume the body here — CHANGELOG.md is intentionally NOT | |
| # updated on unstable publishes (it's reserved for stable cuts; the | |
| # per-bump unstable detail is on the GitHub Releases page). | |
| FRAGMENT_FILE="$RUNNER_TEMP_DIR/changelog-fragment.md" | |
| PREV_TAG="$PREV_TAG" \ | |
| NEW_TAG="$NEW_TAG" \ | |
| NEXT_NPM="$NEXT_NPM" \ | |
| NEXT_PLUGIN="$NEXT_PLUGIN" \ | |
| NPM_DIST_TAG="$NPM_DIST_TAG" \ | |
| REPO="$REPO" \ | |
| RELEASE_BODY_FILE="$BODY_FILE" \ | |
| CHANGELOG_FRAGMENT_FILE="$FRAGMENT_FILE" \ | |
| NODE_NO_WARNINGS=1 pnpm --filter @cardstack/boxel-cli exec \ | |
| node scripts/generate-release-notes.ts | |
| echo "has=true" >> "$GITHUB_OUTPUT" | |
| echo "body_file=$BODY_FILE" >> "$GITHUB_OUTPUT" | |
| - name: Commit, tag, and push | |
| id: commit | |
| if: github.event_name == 'push' && steps.pr.outputs.skip != 'true' | |
| env: | |
| NEXT_NPM: ${{ steps.release.outputs.nextNpm }} | |
| NEXT_PLUGIN: ${{ steps.release.outputs.nextPlugin }} | |
| run: | | |
| set -euo pipefail | |
| git add packages/boxel-cli/package.json \ | |
| packages/boxel-cli/plugin/.claude-plugin/plugin.json \ | |
| packages/boxel-cli/plugin/skills | |
| if git diff --cached --quiet; then | |
| echo "No changes to commit (regen produced no diff, bumps both none)." | |
| echo "pushed=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| MSG="chore(release): boxel-cli" | |
| [ -n "$NEXT_NPM" ] && MSG="$MSG npm=$NEXT_NPM" | |
| [ -n "$NEXT_PLUGIN" ] && MSG="$MSG plugin=$NEXT_PLUGIN" | |
| MSG="$MSG [skip ci]" | |
| git commit -m "$MSG" | |
| if [ -n "$NEXT_NPM" ]; then | |
| TAG="boxel-cli-v${NEXT_NPM}" | |
| # Annotated tag so `git push --follow-tags` actually pushes it. | |
| # Lightweight tags are silently skipped by --follow-tags, which | |
| # would leave the tag on the runner only and fail `gh release create`. | |
| git tag -a "$TAG" -m "$TAG" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| fi | |
| git push origin main --follow-tags | |
| echo "pushed=true" >> "$GITHUB_OUTPUT" | |
| - name: Bump to next unstable version | |
| # Manual (`workflow_dispatch`, blank confirm) path only. The push path | |
| # already computes a fresh `-unstable.<n>` via compute-release.ts; this | |
| # step gives the manual path the same guarantee. The manual path | |
| # deliberately doesn't commit the bump back to main, so the repo can't | |
| # track the counter — npm is the source of truth. The script reads the | |
| # published versions and picks the next free `<base>-unstable.<n>`, so a | |
| # manual publish can never collide with an already-published version | |
| # (the E403 this step exists to prevent). The push path resolves its | |
| # counter from npm too (compute-release.ts), so they can't collide either. | |
| if: github.event_name == 'workflow_dispatch' | |
| working-directory: packages/boxel-cli | |
| run: | | |
| set -euo pipefail | |
| node -e ' | |
| const { execSync } = require("child_process"), fs = require("fs"); | |
| const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); | |
| // Drop any existing -unstable.<n> to get the base we iterate on. | |
| const base = pkg.version.split("-unstable.")[0]; | |
| // `npm view ... versions --json` is an array, or a bare string when | |
| // exactly one version is published; `[].concat` normalizes both. | |
| // A non-zero exit (npm outage) is left to abort the run rather than | |
| // be treated as "nothing published" — the latter would pick | |
| // -unstable.0 and re-create the collision this step prevents. | |
| const pub = [].concat(JSON.parse(execSync("npm view @cardstack/boxel-cli versions --json"))); | |
| const re = new RegExp("^" + base.replace(/\./g, "\\.") + "-unstable\\.(\\d+)$"); | |
| const ns = pub.filter((v) => typeof v === "string").map((v) => (v.match(re) || [])[1]).filter((x) => x != null).map(Number); | |
| pkg.version = base + "-unstable." + (ns.length ? Math.max(...ns) + 1 : 0); | |
| fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2) + "\n"); | |
| console.log("next unstable version → " + pkg.version); | |
| ' | |
| - name: Publish to npm | |
| if: github.event_name == 'workflow_dispatch' || (steps.pr.outputs.skip != 'true' && steps.release.outputs.npmBump != 'none') | |
| working-directory: packages/boxel-cli | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| # `pnpm run build` chains `build:test-harness`, which copies | |
| # `packages/host/dist/` into `packages/boxel-cli/bundled-test-harness/` | |
| # (see `packages/boxel-cli/scripts/build-test-harness.ts`). | |
| # Build the host's dev bundle first so that dist exists on | |
| # disk — `vite build --mode=development` is the right mode | |
| # because production strips the test entry (`tests/index.html`) | |
| # entirely. Only sourcemaps are dropped; the resulting harness | |
| # is ~60MB unpacked / ~15MB compressed. | |
| # | |
| # Build workspace deps in topological order before the host: | |
| # * @cardstack/boxel-icons — boxel-ui's `build:types` resolves | |
| # `@cardstack/boxel-icons/*` against its `declarations/`, | |
| # which only exists after the icons package is built. | |
| # * @cardstack/boxel-ui — the host's vite build imports | |
| # `@cardstack/boxel-ui/styles/global.css`, which resolves | |
| # to the addon's `dist/`. | |
| # Plain `pnpm --filter <name>` does NOT include workspace | |
| # dependencies; they must be built explicitly (or with the | |
| # `<name>...` syntax). Without this chain the host build fails | |
| # with "Rolldown failed to resolve import | |
| # @cardstack/boxel-ui/styles/global.css" — and before that, | |
| # boxel-ui's own type build can fail on missing boxel-icons | |
| # declarations. | |
| pnpm --filter @cardstack/boxel-icons build | |
| pnpm --filter @cardstack/boxel-ui build | |
| pnpm --filter @cardstack/host build | |
| pnpm run build | |
| # Use --no-git-checks because the workflow's commit + tag is already | |
| # pushed; pnpm's pre-publish git-state check would otherwise complain. | |
| pnpm publish --tag unstable --access public --provenance --no-git-checks | |
| - name: Create GitHub Release (prerelease) | |
| if: github.event_name == 'push' && steps.pr.outputs.skip != 'true' && steps.release.outputs.npmBump != 'none' && steps.commit.outputs.tag != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TAG: ${{ steps.commit.outputs.tag }} | |
| NEXT_NPM: ${{ steps.release.outputs.nextNpm }} | |
| NOTES_HAS: ${{ steps.notes.outputs.has }} | |
| NOTES_BODY_FILE: ${{ steps.notes.outputs.body_file }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$NOTES_HAS" = "true" ] && [ -f "$NOTES_BODY_FILE" ]; then | |
| gh release create "$TAG" \ | |
| --title "@cardstack/boxel-cli v${NEXT_NPM}" \ | |
| --notes-file "$NOTES_BODY_FILE" \ | |
| --prerelease | |
| else | |
| # Bootstrap fallback: no prior boxel-cli-v* tag, no auto-notes. | |
| NPM_URL="https://www.npmjs.com/package/@cardstack/boxel-cli/v/${NEXT_NPM}" | |
| gh release create "$TAG" \ | |
| --title "@cardstack/boxel-cli v${NEXT_NPM}" \ | |
| --notes "Auto-published to npm under dist-tag \`unstable\`: ${NPM_URL}" \ | |
| --prerelease | |
| fi | |
| stable: | |
| name: Promote latest unstable to stable | |
| # Any non-empty `confirm` routes here so the validation step below can | |
| # error loudly on a typo. Gating on `confirm == 'promote'` here would make | |
| # a typo skip both jobs and look like a successful no-op run. | |
| if: github.event_name == 'workflow_dispatch' && inputs.confirm != '' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Validate confirmation | |
| run: | | |
| if [ "${{ inputs.confirm }}" != "promote" ]; then | |
| echo "::error::Pass 'promote' as the confirm input to proceed." | |
| exit 1 | |
| fi | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: main | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: ./.github/actions/init | |
| - name: Configure git | |
| run: | | |
| git config user.name "${{ github.actor }}" | |
| git config user.email "${{ github.actor }}@users.noreply.github.com" | |
| - name: Strip -unstable.N from package.json | |
| id: strip | |
| working-directory: packages/boxel-cli | |
| run: | | |
| set -euo pipefail | |
| CURRENT=$(node -p "require('./package.json').version") | |
| echo "Current version: $CURRENT" | |
| # Match <base>-unstable.<n>. If no suffix, the package is already | |
| # on a stable version — refuse to no-op so we don't accidentally | |
| # re-publish identical bits under a new tag. | |
| if [[ "$CURRENT" != *-unstable.* ]]; then | |
| echo "::error::Version $CURRENT is already stable; nothing to promote." | |
| exit 1 | |
| fi | |
| STABLE="${CURRENT%-unstable.*}" | |
| echo "Promoting to: $STABLE" | |
| STABLE="$STABLE" node -e ' | |
| const fs = require("fs"); | |
| const j = JSON.parse(fs.readFileSync("package.json", "utf8")); | |
| j.version = process.env.STABLE; | |
| fs.writeFileSync("package.json", JSON.stringify(j, null, 2) + "\n"); | |
| ' | |
| echo "version=$STABLE" >> "$GITHUB_OUTPUT" | |
| - name: Build boxel-cli | |
| working-directory: packages/boxel-cli | |
| run: | | |
| set -euo pipefail | |
| # See the unstable job's "Publish to npm" step for the full | |
| # rationale on the dep ordering — `build:test-harness` reads from | |
| # `packages/host/dist/`, so the host's dev bundle has to exist | |
| # before we can build the bundled test harness, and the host's vite | |
| # build in turn needs `@cardstack/boxel-ui`'s `dist/`, which itself | |
| # needs `@cardstack/boxel-icons`'s `declarations/` for its type | |
| # build. Plain `pnpm --filter <name>` does NOT include workspace | |
| # deps, so they have to be built explicitly. | |
| pnpm --filter @cardstack/boxel-icons build | |
| pnpm --filter @cardstack/boxel-ui build | |
| pnpm --filter @cardstack/host build | |
| pnpm build | |
| - name: Generate release notes | |
| id: notes | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| VERSION: ${{ steps.strip.outputs.version }} | |
| REPO: ${{ github.repository }} | |
| RUNNER_TEMP_DIR: ${{ runner.temp }} | |
| run: | | |
| set -euo pipefail | |
| NEW_TAG="boxel-cli-v${VERSION}" | |
| # Find the previous stable boxel-cli-v* tag (skipping any -unstable.* | |
| # tags). We diff against the prior stable so the release notes for a | |
| # stable cut aggregate every PR since the previous stable, not just | |
| # the most recent unstable's single PR. | |
| PREV_TAG=$(git tag --list 'boxel-cli-v*' \ | |
| | grep -v -- '-unstable\.' \ | |
| | sort -V \ | |
| | grep -v -x "$NEW_TAG" \ | |
| | tail -n 1 || true) | |
| if [ -z "$PREV_TAG" ]; then | |
| echo "No prior stable boxel-cli-v* tag found (bootstrap). Falling back to one-line release body." | |
| echo "has=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Previous stable tag: $PREV_TAG" | |
| BODY_FILE="$RUNNER_TEMP_DIR/release-body.md" | |
| FRAGMENT_FILE="$RUNNER_TEMP_DIR/changelog-fragment.md" | |
| PREV_TAG="$PREV_TAG" \ | |
| NEW_TAG="$NEW_TAG" \ | |
| NEXT_NPM="$VERSION" \ | |
| NEXT_PLUGIN="" \ | |
| NPM_DIST_TAG="latest" \ | |
| REPO="$REPO" \ | |
| RELEASE_BODY_FILE="$BODY_FILE" \ | |
| CHANGELOG_FRAGMENT_FILE="$FRAGMENT_FILE" \ | |
| NODE_NO_WARNINGS=1 pnpm --filter @cardstack/boxel-cli exec \ | |
| node scripts/generate-release-notes.ts | |
| FRAG_FILE="$FRAGMENT_FILE" node -e ' | |
| const fs = require("fs"); | |
| const path = "packages/boxel-cli/CHANGELOG.md"; | |
| const ANCHOR = "<!-- New entries are inserted directly below this line"; | |
| const fragment = fs.readFileSync(process.env.FRAG_FILE, "utf8"); | |
| const existing = fs.readFileSync(path, "utf8"); | |
| const idx = existing.indexOf(ANCHOR); | |
| let head, tail; | |
| if (idx === -1) { | |
| head = ""; | |
| tail = existing; | |
| } else { | |
| const lineEnd = existing.indexOf("\n", idx); | |
| head = existing.slice(0, lineEnd + 1); | |
| tail = existing.slice(lineEnd + 1); | |
| } | |
| fs.writeFileSync(path, head + "\n" + fragment + "\n" + tail); | |
| ' | |
| echo "has=true" >> "$GITHUB_OUTPUT" | |
| echo "body_file=$BODY_FILE" >> "$GITHUB_OUTPUT" | |
| - name: Commit and tag stable | |
| env: | |
| VERSION: ${{ steps.strip.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| TAG="boxel-cli-v${VERSION}" | |
| # Guard against an orphan tag from a prior failed promotion. If the | |
| # tag exists, the previous run pushed it but failed before publish — | |
| # operator needs to delete the orphan (`git push origin :refs/tags/$TAG`) | |
| # and verify npm state before re-running. | |
| if git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null; then | |
| echo "::error::Tag $TAG already exists. A prior promotion likely failed mid-flight. Delete the orphan tag and verify npm state before re-running." | |
| exit 1 | |
| fi | |
| git add packages/boxel-cli/package.json packages/boxel-cli/CHANGELOG.md | |
| git commit -m "Release @cardstack/boxel-cli v${VERSION} [skip ci]" | |
| # Annotated tag so `git push --follow-tags` actually pushes it. | |
| git tag -a "$TAG" -m "$TAG" | |
| git push origin main --follow-tags | |
| - name: Publish to npm under latest | |
| working-directory: packages/boxel-cli | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: pnpm publish --access public --provenance --no-git-checks | |
| - name: Create GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| VERSION: ${{ steps.strip.outputs.version }} | |
| NOTES_HAS: ${{ steps.notes.outputs.has }} | |
| NOTES_BODY_FILE: ${{ steps.notes.outputs.body_file }} | |
| run: | | |
| set -euo pipefail | |
| TAG="boxel-cli-v${VERSION}" | |
| if [ "$NOTES_HAS" = "true" ] && [ -f "$NOTES_BODY_FILE" ]; then | |
| gh release create "$TAG" \ | |
| --title "@cardstack/boxel-cli v${VERSION}" \ | |
| --notes-file "$NOTES_BODY_FILE" | |
| else | |
| NPM_URL="https://www.npmjs.com/package/@cardstack/boxel-cli/v/${VERSION}" | |
| gh release create "$TAG" \ | |
| --title "@cardstack/boxel-cli v${VERSION}" \ | |
| --notes "Promoted from unstable. Published to npm under dist-tag \`latest\`: ${NPM_URL}" | |
| fi |