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
33 changes: 29 additions & 4 deletions .github/workflows/_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ on:
required: true
type: boolean
secrets:
PUBLISH_TOKEN:
BRAINTRUST_BOT_APP_ID:
description: "braintrust-bot GitHub App id; mints the distribution-repo token."
required: true
BRAINTRUST_BOT_PRIVATE_KEY:
description: "braintrust-bot GitHub App private key."
required: true
OPENAI_API_KEY:
description: "For the post-deploy codex smoke test; skipped if unset."
Expand Down Expand Up @@ -75,12 +79,33 @@ jobs:
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "dist_tag=$dist_tag" >> "$GITHUB_OUTPUT"
dist_repo="${{ inputs.dist_repo }}"
if ! printf '%s' "$dist_repo" | grep -Eq '^[^/[:space:]]+/[^/[:space:]]+$'; then
echo "::error::dist_repo '$dist_repo' must be owner/name."; exit 1
fi
echo "dist_owner=${dist_repo%%/*}" >> "$GITHUB_OUTPUT"
echo "dist_name=${dist_repo#*/}" >> "$GITHUB_OUTPUT"
echo "Releasing $tag -> ${{ inputs.dist_repo }}@$dist_tag (record=${{ inputs.record }})"

# Cross-repo work runs as the braintrust-bot GitHub App instead of a
# long-lived PAT: the token is minted per run, expires in an hour, and is
# scoped to contents:write on the one distribution repo. Monorepo commits
# and tags still use the built-in GITHUB_TOKEN. This step fails loudly if
# braintrust-bot is not installed on <dist_repo>.
- name: Generate distribution-repo 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: ${{ steps.vars.outputs.dist_owner }}
repositories: ${{ steps.vars.outputs.dist_name }}
permission-contents: write

- name: Validate distribution release tag
if: ${{ inputs.record }}
env:
GH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
DIST_REPO: ${{ inputs.dist_repo }}
DIST_TAG: ${{ steps.vars.outputs.dist_tag }}
run: |
Expand Down Expand Up @@ -149,13 +174,13 @@ jobs:
- name: Deploy to distribution repo
env:
PUBLISH_TARGETS: "${{ inputs.plugin }}:${{ inputs.dist_repo }}"
GH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: make publish

- name: Tag and release distribution repo
if: ${{ inputs.record }}
env:
GH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
DIST_REPO: ${{ inputs.dist_repo }}
DIST_TAG: ${{ steps.vars.outputs.dist_tag }}
run: |
Expand Down
31 changes: 28 additions & 3 deletions .github/workflows/smoke-codex.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ on:
required: true
type: string
secrets:
PUBLISH_TOKEN:
BRAINTRUST_BOT_APP_ID:
required: true
BRAINTRUST_BOT_PRIVATE_KEY:
required: true
OPENAI_API_KEY:
required: false
Expand Down Expand Up @@ -64,6 +66,18 @@ jobs:
- name: Checkout monorepo
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Split dist repo into owner/name
id: dist
env:
DIST_REPO: ${{ inputs.dist_repo }}
run: |
set -euo pipefail
if ! printf '%s' "$DIST_REPO" | grep -Eq '^[^/[:space:]]+/[^/[:space:]]+$'; then
echo "::error::dist_repo '$DIST_REPO' must be owner/name."; exit 1
fi
echo "owner=${DIST_REPO%%/*}" >> "$GITHUB_OUTPUT"
echo "name=${DIST_REPO#*/}" >> "$GITHUB_OUTPUT"

- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
Expand All @@ -72,16 +86,27 @@ jobs:
- name: Install Codex and bt CLIs
run: |
npm install -g @openai/codex
curl -fsSL https://bt.dev/cli/install.sh | sh
curl -fsSL https://bt.dev/cli/install.sh | bash
echo "$HOME/.local/bin" >> "$GITHUB_PATH"

- name: Require daemon-capable bt
run: |
"$HOME/.local/bin/bt" trace hook --help

# Read-only marketplace clone, as braintrust-bot rather than a PAT.
- name: Generate distribution-repo 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: ${{ steps.dist.outputs.owner }}
repositories: ${{ steps.dist.outputs.name }}
permission-contents: read

- name: Install plugin from ${{ inputs.dist_repo }}
env:
GH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
git config --global url."https://x-access-token:${GH_TOKEN}@github.com/".insteadOf "https://github.com/"
codex plugin marketplace add "${{ inputs.dist_repo }}"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ on:
workflow_dispatch:
inputs:
version:
description: "Release version, e.g. v0.0.4"
description: "Version to stamp into the build, e.g. v0.0.4. NOTE: nothing mutated or tagged in this monorepo"
required: true
type: string
plugin:
description: "Plugin bundle to release"
description: "Plugin bundle to release. Overwrites braintrustdata/test-coding-agent-dist"
required: true
type: choice
options: [antigravity, claude, codex]
Expand Down
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ branch revision are cancelled.

## Secrets

- `PUBLISH_TOKEN` grants `contents:write` on distribution repositories.
- `BRAINTRUST_BOT_APP_ID` / `BRAINTRUST_BOT_PRIVATE_KEY` are the
`braintrustdata/braintrust-bot` GitHub App credentials. Release workflows mint
a short-lived installation token from them, scoped to `contents:write` on the
one distribution repository being deployed. The app must be installed on every
distribution repository, or the token step fails.
- `OPENAI_API_KEY` enables the optional real Codex smoke test.

Braintrust authentication is deliberately not stored in plugin or daemon
Expand Down
Loading