Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 47 additions & 9 deletions .github/workflows/_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
#
# Always: bump each of the agent's plugin manifest versions
# (.<agent>-plugin/plugin.json), build, and `make publish` to <dist_repo>.
# When record=true (production): also commit the bump to main, tag
# v<version>-<plugin>, 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<version>-<plugin>, and create a GitHub Release on the monorepo. After the
# distribution is deployed, its repo gets an unsuffixed v<version> 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

Expand Down Expand Up @@ -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
Expand All @@ -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 }}
Expand All @@ -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 }}" \
Expand All @@ -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.
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
# claude -> braintrustdata/braintrust-claude-plugin
# codex -> braintrustdata/braintrust-codex-plugin
#
# Full flow: bump version -> commit to main -> tag v<version>-<plugin> ->
# 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<version>-<plugin> -> deploy -> distribution-repo
# tag/release using v<version>. For a safe dry run, use test-release.yml
# (deploys to the sandbox repo and skips all commits, tags, and releases).

name: Release plugin

Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/test-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Loading