prepare release #1094
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: Release | |
| run-name: prepare release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| release: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| permissions: | |
| actions: write | |
| contents: write | |
| id-token: write | |
| pull-requests: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.3.11 | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| - name: Update npm for trusted publishing | |
| run: | | |
| npm install -g npm@latest | |
| npm --version | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Create or update release pull request | |
| id: changesets | |
| uses: changesets/action@v1 | |
| with: | |
| # @changesets/changelog-github occasionally receives truncated | |
| # GitHub GraphQL responses. Retry only that transient failure mode. | |
| version: >- | |
| bash -c 'for attempt in 1 2 3; do log="$(mktemp)"; if bun run changeset:version >"$log" 2>&1; then cat "$log"; rm -f "$log"; exit 0; else status=$?; fi; cat "$log"; if ! grep -Eq "Failed to parse data from GitHub|Premature close" "$log" || [ "$attempt" -eq 3 ]; then rm -f "$log"; exit "$status"; fi; echo "::warning::changeset:version hit a transient GitHub GraphQL failure on attempt $attempt; resetting generated files before retry."; rm -f "$log"; git reset --hard HEAD; git clean -fd -- .changeset apps packages examples e2e; done' | |
| commit: Version Packages | |
| title: Version Packages | |
| createGithubReleases: false | |
| env: | |
| # PAT (RELEASE_PAT) so the auto-opened Version Packages PR | |
| # triggers downstream workflows (pkg-pr-new, CI). PRs authored | |
| # by the default GITHUB_TOKEN do not trigger other workflows by | |
| # GitHub design. Falls back to GITHUB_TOKEN when the secret is | |
| # not set, so the workflow keeps working in forks / before the | |
| # secret is configured. | |
| GITHUB_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }} | |
| - name: Smoke test packed @executor-js library packages | |
| if: steps.changesets.outputs.hasChangesets == 'false' | |
| run: bun run release:smoke:packages | |
| - name: Publish @executor-js library packages | |
| if: steps.changesets.outputs.hasChangesets == 'false' | |
| run: bun run release:publish:packages | |
| - name: Detect release version change | |
| if: steps.changesets.outputs.hasChangesets == 'false' | |
| id: detect_release | |
| run: | | |
| before="${{ github.event.before }}" | |
| if [ "$before" = "0000000000000000000000000000000000000000" ]; then | |
| before="$(git rev-list --max-count=1 HEAD^ 2>/dev/null || true)" | |
| fi | |
| version="$(node -e "console.log(JSON.parse(require('fs').readFileSync('apps/cli/package.json', 'utf8')).version)")" | |
| if [ -n "$before" ] && git cat-file -e "$before:apps/cli/package.json" 2>/dev/null; then | |
| previous_version="$(git show "$before:apps/cli/package.json" | node -e "let data = ''; process.stdin.setEncoding('utf8'); process.stdin.on('data', (chunk) => { data += chunk; }); process.stdin.on('end', () => { console.log(JSON.parse(data).version ?? ''); });")" | |
| else | |
| previous_version="" | |
| fi | |
| release_tag="v$version" | |
| if [ -n "$previous_version" ] && [ "$previous_version" != "$version" ]; then | |
| echo "changed=true" >> "$GITHUB_OUTPUT" | |
| elif ! git ls-remote --exit-code --tags origin "refs/tags/$release_tag" >/dev/null 2>&1; then | |
| echo "changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| - name: Validate release tag | |
| if: steps.changesets.outputs.hasChangesets == 'false' && steps.detect_release.outputs.changed == 'true' | |
| id: validate_release | |
| env: | |
| RELEASE_VERSION: ${{ steps.detect_release.outputs.version }} | |
| run: bun run scripts/validate-release-ref.ts --version-env RELEASE_VERSION --output tag | |
| - name: Create and push release tag | |
| if: steps.changesets.outputs.hasChangesets == 'false' && steps.detect_release.outputs.changed == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.RELEASE_PAT || github.token }} | |
| RELEASE_TAG: ${{ steps.validate_release.outputs.tag }} | |
| run: | | |
| auth_remote="https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" | |
| if git ls-remote --exit-code --tags "$auth_remote" "refs/tags/$RELEASE_TAG" >/dev/null 2>&1; then | |
| echo "Tag $RELEASE_TAG already exists." | |
| exit 0 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git tag "$RELEASE_TAG" | |
| git push "$auth_remote" "$RELEASE_TAG" | |
| # Publishing is intentionally tag-driven: pushing the validated v* tag | |
| # triggers publish-executor-package.yml. A second workflow_dispatch path | |
| # races a duplicate publish for the same release. | |
| # Desktop build downloads CLI binaries from the release, so it must | |
| # run after CLI publish completes. Trigger it from the CLI workflow | |
| # or manually via: gh workflow run publish-desktop.yml -f tag=vX.Y.Z |