diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fec606b..d2e6f19 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,19 +7,24 @@ on: description: "Version to release, e.g. 0.2.0 (no leading v)" required: true type: string + push: + branches: [main] + paths: + - plugins/trace-codex/.codex-plugin/plugin.json permissions: contents: write + pull-requests: write env: PLUGIN_DIR: plugins/trace-codex MANIFEST: plugins/trace-codex/.codex-plugin/plugin.json jobs: - release: + # Phase 1: open a release PR that bumps the manifest version. + prepare: + if: github.event_name == 'workflow_dispatch' runs-on: ubuntu-24.04 - outputs: - version: ${{ steps.vars.outputs.version }} steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 @@ -44,19 +49,16 @@ jobs: fi echo "version=$version" >> "$GITHUB_OUTPUT" echo "tag=trace-codex-v$version" >> "$GITHUB_OUTPUT" + echo "branch=release/trace-codex-v$version" >> "$GITHUB_OUTPUT" - name: Ensure tag does not already exist run: | + git fetch --tags --quiet if git rev-parse "refs/tags/${{ steps.vars.outputs.tag }}" >/dev/null 2>&1; then echo "::error::Tag ${{ steps.vars.outputs.tag }} already exists." exit 1 fi - - name: Install Bun - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 - with: - bun-version: latest - - name: Update plugin manifest version run: | tmp="$(mktemp)" @@ -67,17 +69,79 @@ jobs: # Fail if the bump did not take (e.g. unexpected manifest format). grep -q '"version": "${{ steps.vars.outputs.version }}"' "$MANIFEST" - - name: Commit, tag, and push + - name: Create release branch and open PR + env: + GH_TOKEN: ${{ github.token }} run: | + branch="${{ steps.vars.outputs.branch }}" + version="${{ steps.vars.outputs.version }}" + + if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then + echo "::error::Branch $branch already exists on origin. Delete it or pick a new version." + exit 1 + fi + git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" + git switch -c "$branch" git add "$MANIFEST" - git commit -m "chore(trace-codex): release v${{ steps.vars.outputs.version }}" - git tag "${{ steps.vars.outputs.tag }}" - git push origin HEAD - git push origin "${{ steps.vars.outputs.tag }}" + git commit -m "chore(trace-codex): release v$version" + git push origin "$branch" + + gh pr create \ + --base main \ + --head "$branch" \ + --title "chore(trace-codex): release v$version" \ + --body "Automated release PR for trace-codex v$version. + + Merging this PR (squash) updates the manifest version on main and + triggers the publish job, which builds binaries, creates the + \`${{ steps.vars.outputs.tag }}\` tag + GitHub release, and runs the + smoke test. + + Review the manifest bump, then approve and squash-merge." + + # Phase 2: publish once the version bump lands on main via the merged PR. + publish: + if: github.event_name == 'push' + runs-on: ubuntu-24.04 + outputs: + version: ${{ steps.vars.outputs.version }} + published: ${{ steps.vars.outputs.published }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + fetch-depth: 0 + + - name: Read manifest version and decide whether to publish + id: vars + run: | + version="$(grep '"version"' "$MANIFEST" | head -n1 | sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')" + if ! printf '%s' "$version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Manifest version '$version' is not valid semver." + exit 1 + fi + tag="trace-codex-v$version" + echo "version=$version" >> "$GITHUB_OUTPUT" + echo "tag=$tag" >> "$GITHUB_OUTPUT" + + git fetch --tags --quiet + if git rev-parse "refs/tags/$tag" >/dev/null 2>&1; then + echo "Tag $tag already exists; nothing to publish." + echo "published=false" >> "$GITHUB_OUTPUT" + else + echo "Tag $tag not found; will publish." + echo "published=true" >> "$GITHUB_OUTPUT" + fi + + - name: Install Bun + if: steps.vars.outputs.published == 'true' + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + with: + bun-version: latest - name: Build release binaries + if: steps.vars.outputs.published == 'true' working-directory: ${{ env.PLUGIN_DIR }} run: | bun install --frozen-lockfile @@ -85,7 +149,14 @@ jobs: bun run build ls -la bin/ + - name: Create and push tag + if: steps.vars.outputs.published == 'true' + run: | + git tag "${{ steps.vars.outputs.tag }}" + git push origin "${{ steps.vars.outputs.tag }}" + - name: Create GitHub release with autogenerated notes + if: steps.vars.outputs.published == 'true' env: GH_TOKEN: ${{ github.token }} run: | @@ -101,9 +172,10 @@ jobs: # After a successful publish, run the end-to-end smoke test (macOS + Linux) # against the just-released version. smoke: - needs: release + needs: publish + if: needs.publish.outputs.published == 'true' uses: ./.github/workflows/smoke.yaml with: - version: ${{ needs.release.outputs.version }} + version: ${{ needs.publish.outputs.version }} secrets: openai_api_key: ${{ secrets.OPENAI_API_KEY }}