Prepare grok v0.0.4 #52
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
| # Prepare a release PR on manual dispatch; publish its exact merge commit when | |
| # the PR is merged. Both stages appear under Release Plugin as separate runs. | |
| # For deploy-only sandbox runs, use test-release.yml. | |
| name: Release Plugin | |
| run-name: >- | |
| ${{ github.event_name == 'workflow_dispatch' | |
| && format('Prepare {0} {1}', inputs.plugin, inputs.version) | |
| || github.event.pull_request.merged | |
| && github.event.pull_request.head.repo.full_name == github.repository | |
| && startsWith(github.event.pull_request.head.ref, 'release/') | |
| && format('Publish {0} (PR #{1})', github.event.pull_request.head.ref, github.event.pull_request.number) | |
| || format('No release (PR #{0} closed)', github.event.pull_request.number) }} | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Release version, e.g. v0.0.4" | |
| required: true | |
| type: string | |
| plugin: | |
| description: "Plugin bundle to release" | |
| required: true | |
| type: choice | |
| options: [antigravity, claude, codex, grok] | |
| pull_request: | |
| types: [closed] | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| prepare: | |
| name: Prepare release PR | |
| if: github.event_name == 'workflow_dispatch' | |
| concurrency: | |
| group: prepare-release-${{ inputs.plugin }} | |
| cancel-in-progress: false | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Validate release request | |
| id: vars | |
| env: | |
| REQUESTED_VERSION: ${{ inputs.version }} | |
| PLUGIN: ${{ inputs.plugin }} | |
| SOURCE_REF: ${{ github.ref }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$SOURCE_REF" != "refs/heads/main" ]; then | |
| echo "::error::Release preparation must run on main." | |
| exit 1 | |
| fi | |
| version="${REQUESTED_VERSION#v}" | |
| if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "::error::version must be semver (MAJOR.MINOR.PATCH)." | |
| exit 1 | |
| fi | |
| case "$PLUGIN" in | |
| antigravity) dist_repo=braintrustdata/braintrust-antigravity-plugin ;; | |
| claude) dist_repo=braintrustdata/braintrust-claude-plugin ;; | |
| codex) dist_repo=braintrustdata/braintrust-codex-plugin ;; | |
| grok) dist_repo=braintrustdata/braintrust-grok-plugin ;; | |
| *) echo "::error::Unsupported release plugin."; exit 1 ;; | |
| esac | |
| { | |
| printf 'version=%s\n' "$version" | |
| printf 'tag=v%s-%s\n' "$version" "$PLUGIN" | |
| printf 'dist_repo=%s\n' "$dist_repo" | |
| printf 'paths<<EOF\n.github/release-versions/%s\n' "$PLUGIN" | |
| case "$PLUGIN" in | |
| claude) printf '%s\n' 'src/plugins/claude/content/plugins/*/.claude-plugin/plugin.json' ;; | |
| codex) printf '%s\n' 'src/plugins/codex/content/plugins/*/.codex-plugin/plugin.json' ;; | |
| grok) printf '%s\n' 'src/plugins/grok/content/.grok-plugin/plugin.json' 'src/plugins/grok/content/hooks/forward.sh' ;; | |
| esac | |
| printf 'EOF\n' | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Checkout main | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| ref: main | |
| fetch-depth: 0 | |
| - name: Reject existing release requests | |
| id: preflight | |
| env: | |
| PLUGIN: ${{ inputs.plugin }} | |
| VERSION: ${{ steps.vars.outputs.version }} | |
| TAG: ${{ steps.vars.outputs.tag }} | |
| run: | | |
| set -euo pipefail | |
| if cmp -s <(printf '%s\n' "$VERSION") ".github/release-versions/$PLUGIN"; then | |
| echo "::error::Release version is already merged; rerun its publication run in Release Plugin." | |
| exit 1 | |
| fi | |
| if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then | |
| echo "::error::Source release tag $TAG already exists." | |
| exit 1 | |
| fi | |
| # The App must be installed on this monorepo with both permissions. | |
| # Its short-lived token lets the release PR trigger normal pull-request CI. | |
| - name: Generate monorepo token | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| app-id: ${{ secrets.BRAINTRUST_BOT_APP_ID }} | |
| private-key: ${{ secrets.BRAINTRUST_BOT_PRIVATE_KEY }} | |
| owner: ${{ github.repository_owner }} | |
| repositories: ${{ github.event.repository.name }} | |
| permission-contents: write | |
| permission-pull-requests: write | |
| - name: Prepare release files | |
| id: prepare | |
| env: | |
| PLUGIN: ${{ inputs.plugin }} | |
| VERSION: ${{ steps.vars.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$PLUGIN" != "antigravity" ]; then | |
| python3 scripts/set-plugin-version.py "$PLUGIN" "$VERSION" | |
| fi | |
| mkdir -p .github/release-versions | |
| printf '%s\n' "$VERSION" > ".github/release-versions/$PLUGIN" | |
| - name: Create release pull request | |
| id: release-pr | |
| uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| base: main | |
| branch: release/${{ inputs.plugin }}/v${{ steps.vars.outputs.version }} | |
| add-paths: ${{ steps.vars.outputs.paths }} | |
| commit-message: "chore(${{ inputs.plugin }}): release v${{ steps.vars.outputs.version }}" | |
| title: "chore(${{ inputs.plugin }}): release v${{ steps.vars.outputs.version }}" | |
| body: | | |
| Prepare `${{ inputs.plugin }}` version `${{ steps.vars.outputs.version }}`. | |
| Production destination: `${{ steps.vars.outputs.dist_repo }}`. | |
| Human approval and merge into `main` authorize tagging the merge commit and publishing this version to the production destination. This preparation does not tag or deploy anything. | |
| - name: Summarize release pull request | |
| id: summary | |
| env: | |
| PR_URL: ${{ steps.release-pr.outputs.pull-request-url }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "$PR_URL" ]; then | |
| echo "::error::No release pull request was created or updated." | |
| exit 1 | |
| fi | |
| printf 'Release pull request: %s\n' "$PR_URL" >> "$GITHUB_STEP_SUMMARY" | |
| printf '\nPreparation is complete. Merging the PR starts a publication run under Release Plugin; closing it without merging does not publish.\n' >> "$GITHUB_STEP_SUMMARY" | |
| resolve: | |
| name: Resolve merged release | |
| if: >- | |
| github.event_name == 'pull_request' && | |
| github.event.pull_request.merged == true && | |
| github.event.pull_request.head.repo.full_name == github.repository && | |
| startsWith(github.event.pull_request.head.ref, 'release/') | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read | |
| outputs: | |
| plugin: ${{ steps.vars.outputs.plugin }} | |
| version: ${{ steps.vars.outputs.version }} | |
| source_sha: ${{ steps.vars.outputs.source_sha }} | |
| dist_repo: ${{ steps.vars.outputs.dist_repo }} | |
| steps: | |
| - name: Resolve merged release request | |
| id: vars | |
| env: | |
| PR_MERGED: ${{ github.event.pull_request.merged }} | |
| PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} | |
| SOURCE_REPO: ${{ github.repository }} | |
| PR_BASE_REF: ${{ github.event.pull_request.base.ref }} | |
| RELEASE_BRANCH: ${{ github.event.pull_request.head.ref }} | |
| SOURCE_SHA: ${{ github.event.pull_request.merge_commit_sha }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$PR_MERGED" != "true" ] || [ "$PR_HEAD_REPO" != "$SOURCE_REPO" ] || [ "$PR_BASE_REF" != "main" ]; then | |
| echo "::error::Production releases require a merged same-repository PR targeting main." | |
| exit 1 | |
| fi | |
| if [[ ! "$RELEASE_BRANCH" =~ ^release/(antigravity|claude|codex|grok)/v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then | |
| echo "::error::Malformed release branch; expected release/<plugin>/vMAJOR.MINOR.PATCH." | |
| exit 1 | |
| fi | |
| plugin="${BASH_REMATCH[1]}" | |
| version="${BASH_REMATCH[2]}" | |
| if [[ ! "$SOURCE_SHA" =~ ^[0-9a-f]{40}$ ]]; then | |
| echo "::error::The merged release must have a full lowercase commit SHA." | |
| exit 1 | |
| fi | |
| case "$plugin" in | |
| antigravity) dist_repo=braintrustdata/braintrust-antigravity-plugin ;; | |
| claude) dist_repo=braintrustdata/braintrust-claude-plugin ;; | |
| codex) dist_repo=braintrustdata/braintrust-codex-plugin ;; | |
| grok) dist_repo=braintrustdata/braintrust-grok-plugin ;; | |
| esac | |
| { | |
| printf 'plugin=%s\n' "$plugin" | |
| printf 'version=%s\n' "$version" | |
| printf 'source_sha=%s\n' "$SOURCE_SHA" | |
| printf 'dist_repo=%s\n' "$dist_repo" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Checkout approved merge commit | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| ref: ${{ steps.vars.outputs.source_sha }} | |
| fetch-depth: 0 | |
| - name: Verify approved release marker | |
| id: marker | |
| env: | |
| PLUGIN: ${{ steps.vars.outputs.plugin }} | |
| VERSION: ${{ steps.vars.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| if ! cmp -s <(printf '%s\n' "$VERSION") ".github/release-versions/$PLUGIN"; then | |
| echo "::error::The approved release marker must contain exactly the requested version and a newline." | |
| exit 1 | |
| fi | |
| release: | |
| name: Publish approved release | |
| permissions: | |
| contents: write | |
| needs: resolve | |
| uses: ./.github/workflows/_release.yml | |
| with: | |
| plugin: ${{ needs.resolve.outputs.plugin }} | |
| version: ${{ needs.resolve.outputs.version }} | |
| source_sha: ${{ needs.resolve.outputs.source_sha }} | |
| dist_repo: ${{ needs.resolve.outputs.dist_repo }} | |
| record: true | |
| secrets: inherit |