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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ jobs:
fi
- name: Build and validate plugins
run: make test
- name: Build Cursor extension
- name: Package Cursor extension
working-directory: dist/cursor
run: |
npm ci --ignore-scripts --no-audit --no-fund
npm run build
npm run package -- --out "$RUNNER_TEMP/braintrust-cursor.vsix"

# Pi and OpenCode run inside the user's agent process, so their unit tests
# run on every host OS. Packaging and validation stay in `plugins`.
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ jobs:

Production destination: `${{ steps.vars.outputs.dist_repo }}`.

Cursor releases also publish `braintrustdata.braintrust` to Open VSX using trusted publishing.

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
Expand Down Expand Up @@ -245,3 +247,56 @@ jobs:
dist_repo: ${{ needs.resolve.outputs.dist_repo }}
record: true
secrets: inherit

publish-cursor-openvsx:
name: Publish Cursor extension to Open VSX
needs: [resolve, release]
if: needs.resolve.outputs.plugin == 'cursor'
runs-on: ubuntu-24.04
timeout-minutes: 15
environment: openvsx-cursor
permissions:
contents: read
id-token: write
concurrency:
group: cursor-openvsx
cancel-in-progress: false
steps:
- name: Checkout approved release commit
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ needs.resolve.outputs.source_sha }}
persist-credentials: false

- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
cache: npm
cache-dependency-path: src/plugins/cursor/content/package-lock.json

- name: Build and validate Cursor distribution
run: make validate-cursor

- name: Package approved extension
working-directory: dist/cursor
env:
RELEASE_VERSION: ${{ needs.resolve.outputs.version }}
run: |
set -euo pipefail
node -e 'if (require("./package.json").version !== process.env.RELEASE_VERSION) throw new Error("Extension version does not match the approved release")'
npm ci --ignore-scripts --no-audit --no-fund
npm run package -- --out "$RUNNER_TEMP/braintrust-cursor.vsix"

- name: Save extension package
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: braintrust-cursor-${{ needs.resolve.outputs.version }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/braintrust-cursor.vsix
if-no-files-found: error

# Register this monorepo + release.yml + openvsx-cursor in Open VSX.
# Keep the registry job outside _release.yml so sandbox runs cannot publish.
- name: Publish with Open VSX trusted publishing
working-directory: dist/cursor
run: npm run publish:openvsx -- "$RUNNER_TEMP/braintrust-cursor.vsix" --trusted-publishing
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,20 @@ separate event-driven runs under one workflow entry, named `Prepare …` and
publication. It never pushes source changes to `main`. CI runs on release PRs;
the current rules require one approval but do not require passing CI.

Cursor production releases then package and publish `braintrustdata.braintrust`
to Open VSX with GitHub Actions OIDC in the `openvsx-cursor` environment. Register
the monorepo's `release.yml` as the trusted publisher; see
[`src/plugins/cursor/content/CONTRIBUTING.md`](src/plugins/cursor/content/CONTRIBUTING.md#one-time-open-vsx-trusted-publishing-setup)
for the exact configuration. Sandbox releases and manual distribution pushes
do not publish to Open VSX. No Open VSX access-token secret is required.

If publishing is interrupted, rerun the **publication run** in Release Plugin
rather than manually preparing the merged version again. An existing source tag must match the
approved merge SHA; an existing distribution tag still rejects publication.
An unchanged Antigravity artifact may reuse its previous distribution commit
under the new version tag.
If only the Cursor Open VSX job failed after distribution publication succeeded,
use **Re-run failed jobs** to preserve the completed distribution release.

The manual `test-release.yml` workflow calls `_release.yml` at the selected
commit, stamps versions only on the runner, and **overwrites the shared test
Expand Down
62 changes: 58 additions & 4 deletions src/plugins/cursor/content/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ open pull requests in the monorepo.

### Prerequisites

- Node.js 20.18.1 or newer
- Node.js 22 or newer (release CI uses Node.js 24)
- npm

### Build from Source
Expand Down Expand Up @@ -128,9 +128,63 @@ braintrust-coding-agent-plugins/src/plugins/cursor/content/

The monorepo's **Release Plugin** workflow prepares a version pull request.
After that pull request is approved and merged, the workflow publishes the
generated Cursor plugin tree to `braintrustdata/braintrust-cursor-extension`.
generated Cursor plugin tree to `braintrustdata/braintrust-cursor-extension`
and then packages and publishes `braintrustdata.braintrust` to
[Open VSX](https://open-vsx.org/extension/braintrustdata/braintrust).
The version script updates the Cursor plugin manifest, `package.json`, and
`package-lock.json` together. Do not edit the distribution repository directly.

Publishing the VS Code extension to an extension marketplace is a separate
release action. `npm run package` creates a `.vsix` file for local testing.
The Open VSX job checks out the exact approved merge commit, installs locked
dependencies, and packages the extension with `npm run package`. It saves the
VSIX as a workflow artifact before publishing that same file. Pull requests,
release preparation, `test-release.yml`, and `make publish` do not publish to
Open VSX. `npm run package` also creates a VSIX for local testing. Publishing
to the VS Code Marketplace remains a separate action.

### One-time Open VSX trusted publishing setup

The workflow uses
[Open VSX trusted publishing](https://github.com/eclipse-openvsx/openvsx/wiki/Trusted-Publishing)
with GitHub Actions OIDC; it does not need an `OVSX_PAT` secret.

1. In the **monorepo**, create the GitHub Actions environment `openvsx-cursor`
under **Settings → Environments**. The release PR's approval and merge remain
the authorization for publication; required environment reviewers are
optional if you want an additional approval before the Open VSX job runs.
Restrict deployment branches to `main`: for this merged `pull_request`
event, GitHub sets the workflow ref to `refs/heads/main`.
2. Sign in to Open VSX as an **owner** of the `braintrustdata` namespace and
ensure that account has signed the Publisher Agreement. Contributor access
is insufficient to register a trusted publisher.
3. Open [Settings → Trusted Publishers](https://open-vsx.org/user-settings/trusted-publishers),
select the `braintrustdata` namespace and `braintrust` extension, and register
**GitHub Actions** with these exact values:

| Field | Value |
|---|---|
| Organization or User name | `braintrustdata` |
| Repository name | `braintrust-coding-agent-plugins` |
| Workflow filename | `release.yml` |
| Environment name | `openvsx-cursor` |

Register the monorepo workflow, rather than the generated distribution
repository or `_release.yml`. Merge this workflow into `main` before
registering it. The extension must have at least one active published
version; if it has none, a namespace owner must publish an initial version
with an access token before registration is possible. The package's
`publisher` must match the namespace's casing exactly (`braintrustdata`).
4. Keep `OVSX_PAT` out of the publishing job: an access token takes precedence
over OIDC, even with `--trusted-publishing`. Existing Braintrust Bot secrets
still handle distribution-repository deployment; no additional publishing
secret is needed for Open VSX.

### Recovering a failed Open VSX publish

Fix the environment or trusted-publisher registration, then choose **Re-run
failed jobs** on the **Publish …** run in Release Plugin. The Open VSX job is
separate from distribution publication, so successfully completed tag and
deployment jobs are preserved. Re-running all jobs after the distribution
release succeeded fails its existing-tag check. Do not prepare another release
PR for the already-merged version. If an upload succeeded despite a reported
failure, check the published version before retrying; duplicate Open VSX
versions are rejected.
Loading
Loading