diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index ec8a894..4d6d868 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -4,10 +4,11 @@ # # Always: bump each of the agent's plugin manifest versions # (.-plugin/plugin.json), build, and `make publish` to . -# When record=true (production): also commit the bump to main, tag -# v-, and create a GitHub Release on the monorepo. Test runs -# (record=false) skip those so they leave no trace on the monorepo and can be -# re-run with the same version. +# When record=true (production): commit the bump to main when needed, tag +# v-, and create a GitHub Release on the monorepo. After the +# distribution is deployed, its repo gets an unsuffixed v tag and +# matching GitHub Release. Test runs (record=false) skip both sets of release +# records so they leave no trace and can be re-run with the same version. name: _release @@ -60,7 +61,8 @@ jobs: echo "::error::version '${{ inputs.version }}' is not semver (MAJOR.MINOR.PATCH)."; exit 1 fi tag="v$version-${{ inputs.plugin }}" - # Production releases must come from main and not reuse a tag. + dist_tag="v$version" + # Production releases must come from main and not reuse a monorepo tag. if [ "${{ inputs.record }}" = "true" ]; then if [ "${{ github.ref }}" != "refs/heads/main" ]; then echo "::error::Production releases must run on main (got '${{ github.ref }}')."; exit 1 @@ -72,12 +74,29 @@ jobs: fi echo "version=$version" >> "$GITHUB_OUTPUT" echo "tag=$tag" >> "$GITHUB_OUTPUT" - echo "Releasing $tag -> ${{ inputs.dist_repo }} (record=${{ inputs.record }})" + echo "dist_tag=$dist_tag" >> "$GITHUB_OUTPUT" + echo "Releasing $tag -> ${{ inputs.dist_repo }}@$dist_tag (record=${{ inputs.record }})" + + - name: Validate distribution release tag + if: ${{ inputs.record }} + env: + GH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} + DIST_REPO: ${{ inputs.dist_repo }} + DIST_TAG: ${{ steps.vars.outputs.dist_tag }} + run: | + set -euo pipefail + if output="$(gh api "repos/$DIST_REPO/git/ref/tags/$DIST_TAG" 2>&1)"; then + echo "::error::tag $DIST_TAG already exists in $DIST_REPO." + exit 1 + elif [[ "$output" != *"HTTP 404"* ]]; then + printf '%s\n' "$output" >&2 + exit 1 + fi - name: Bump plugin manifest versions run: python3 scripts/set-plugin-version.py "${{ inputs.plugin }}" "${{ steps.vars.outputs.version }}" - - name: Commit, tag, and release on the monorepo + - name: Record monorepo release if: ${{ inputs.record }} env: GH_TOKEN: ${{ github.token }} @@ -86,9 +105,13 @@ jobs: git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add -A - git commit -m "chore(${{ inputs.plugin }}): release v${{ steps.vars.outputs.version }}" + if ! git diff --cached --quiet; then + git commit -m "chore(${{ inputs.plugin }}): release v${{ steps.vars.outputs.version }}" + git push origin HEAD:main + else + echo "Plugin manifests already contain v${{ steps.vars.outputs.version }}; tagging the committed version." + fi git tag "${{ steps.vars.outputs.tag }}" - git push origin HEAD:main git push origin "${{ steps.vars.outputs.tag }}" gh release create "${{ steps.vars.outputs.tag }}" \ --title "${{ steps.vars.outputs.tag }}" \ @@ -100,6 +123,21 @@ jobs: GH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} run: make publish + - name: Tag and release distribution repo + if: ${{ inputs.record }} + env: + GH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} + DIST_REPO: ${{ inputs.dist_repo }} + DIST_TAG: ${{ steps.vars.outputs.dist_tag }} + run: | + set -euo pipefail + target_sha="$(gh api "repos/$DIST_REPO/git/ref/heads/main" --jq '.object.sha')" + gh release create "$DIST_TAG" \ + --repo "$DIST_REPO" \ + --target "$target_sha" \ + --title "$DIST_TAG" \ + --generate-notes + # Post-deploy end-to-end smoke test (codex only): install the just-deployed # plugin from the marketplace on Linux + both macOS arches and assert a real # session traces. It's a verification, not a gate — the deploy already happened. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fdbcf87..0b4106f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,9 +2,10 @@ # claude -> braintrustdata/braintrust-claude-plugin # codex -> braintrustdata/braintrust-codex-plugin # -# Full flow: bump version -> commit to main -> tag v- -> -# GitHub Release -> deploy. For a safe dry run, use test-release.yml (deploys to -# the sandbox repo and skips the monorepo commit/tag/release). +# Full flow: stamp the version -> commit to main when needed -> monorepo +# tag/release using v- -> deploy -> distribution-repo +# tag/release using v. For a safe dry run, use test-release.yml +# (deploys to the sandbox repo and skips all commits, tags, and releases). name: Release plugin diff --git a/.github/workflows/test-release.yml b/.github/workflows/test-release.yml index 560146a..2e00969 100644 --- a/.github/workflows/test-release.yml +++ b/.github/workflows/test-release.yml @@ -2,8 +2,9 @@ # (braintrustdata/test-coding-agent-dist). Same dropdowns as release.yml. # # Exercises the version bump, build, and deploy, but deploys to the test repo -# and does NOT commit/tag/release on the monorepo — so it leaves no trace and -# can be re-run with the same version. Use release.yml for a real release. +# and does NOT commit/tag/release on the monorepo or tag/release the sandbox +# distribution repo — so it can be re-run with the same version. Use +# release.yml for a real release. name: Release plugin (test)