Skip to content

Latest commit

 

History

History
169 lines (104 loc) · 12 KB

File metadata and controls

169 lines (104 loc) · 12 KB

Releasing the VS Code extension

This package (copilotkit-vscode-extension) ships to two registries:

  • VS Code Marketplace — primary, used by VS Code, Cursor, etc.
  • Open VSX — used by VSCodium, Gitpod, OpenVSCode Server, Theia-based IDEs.

The flow mirrors the CopilotKit/aimock release model for publish: a chore: release vX.Y.Z commit on main triggers CI, which self-gates on whether the version is already live and publishes if not. Unlike aimock, contributors don't hand-edit package.json — the VS Code Extension — Metadata Sync workflow (.github/workflows/vscode-extension-changelog-sync.yml) auto-syncs package.json.version (and optionally package.json.description) from the CHANGELOG entry (and optionally the README.md first paragraph) when the PR is opened, and commits chore: release vX.Y.Z on the PR branch for you. No tag is created by hand. No vsce publish is run by hand.

Cutting a release

Cutting a release is one file edit, one commit, one PR.

  1. Prepend an entry to CHANGELOG.md:

    ## 0.1.1 — 2026-04-22
    
    ### Fixed
    
    - Hook Explorer crash on empty workspaces
    
    ### Added
    
    - New "Copy AG-UI run URL" command

    Use Keep-a-Changelog subsections: Added, Changed, Fixed, Removed, Deprecated, Security. The date is whatever date you commit.

    If you also want to change how the extension is described on the Marketplace / Open VSX listing page, edit the first paragraph under the # CopilotKit for VS Code title in README.md in the same PR. The metadata-sync workflow extracts that paragraph, strips inline markdown, and writes it to package.json.description (the field both registries render as the one-liner). First paragraph must stay ≤200 chars — the workflow fails fast otherwise so you don't silently ship a truncated listing.

  2. Commit with any message (e.g. docs: changelog for 0.1.1) and push.

  3. Open a PR.

  4. Automation: the VS Code Extension — Metadata Sync workflow runs on your PR, reads the top version from CHANGELOG and the first paragraph of README.md, and bumps package.json (.version and/or .description) to match. If a version bump is needed it commits chore: release vX.Y.Z; otherwise, if only the description drifted it commits chore(vscode-extension): sync description from README. No action needed from you — just pull the updated branch if you keep working locally.

  5. Review, merge with a merge commit (NOT squash — the chore: release commit needs to land on main so the publish workflow's path filter fires).

On merge, CI auto-publishes to the VS Code Marketplace and Open VSX, tags vscode-extension-vX.Y.Z, cuts a GitHub Release, and posts to #oss-alerts.

Manual escape hatch

If the sync workflow is down or you can't wait, bump package.json yourself in the same PR and use chore: release vX.Y.Z as your own commit subject. Everything downstream works the same.

CI publish flow

On every push to main, .github/workflows/publish-vscode-extension.yml runs:

  1. Reads version from package.json.
  2. Calls vsce show <publisher>.<name> and checks whether that exact version is already listed on the Marketplace.
  3. If already published → no-op (green, zero side effects). This makes every non-release push to main safe.
  4. Otherwise: install, build, vsce package → single extension.vsix, upload artifact.
  5. Marketplace auth is GitHub OIDC → Entra federated Service Principal → vsce publish --azure-credential. No user PAT. The SP is copilotkit-vscode-publish in the copilotkit.ai tenant with Contributor role on the Marketplace copilotkit publisher. azure/login@v2 sources AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_SUBSCRIPTION_ID from the production environment variables (not secrets) and populates the AzureCliCredential chain that vsce reads by default. A verify-pat --azure-credential pre-flight step catches auth issues before we publish.
  6. Publish the same .vsix to Open VSX with $OVSX_PAT (bot-owned PAT, quarterly rotation — OIDC is not yet supported on Open VSX).
  7. Create tag vscode-extension-v<version> and push it.
  8. Cut a GitHub Release using the CHANGELOG section for that version (or auto-generated notes if absent).
  9. Post a Slack message to SLACK_WEBHOOK if configured.

The federated credential on the Entra SP is pinned to subject repo:CopilotKit/vscode-extension:environment:production, which means the workflow's environment: production must match exactly (case-sensitive) for the OIDC token exchange to succeed.

Both publishes use continue-on-error so a partial failure is visible. The final "Report publish results" step fails the job if either registry ultimately failed — you never land in "Marketplace succeeded, Open VSX silently skipped."

Transient registry failures

Both registries occasionally return transient 5xx errors during publish. In particular, Open VSX's /publish endpoint returns intermittent 502 Bad Gateway errors — a known Eclipse Foundation infra issue. VS Code Marketplace is more reliable but can also flake on 502/503/504.

The CI workflow handles this automatically:

  • Each publish step retries up to 5 times with backoff (10s, 20s, 40s, 60s, 90s).
  • Only transient conditions are retried: 5xx, timeouts, connection resets, DNS (EAI_AGAIN). Auth (401/403, TF400813, "Invalid access token") and validation (400/422, manifest errors) fail fast with no retry.
  • A "version already exists" response is treated as idempotent success — this handles the case where attempt N-1 actually landed on the registry but its response never reached us (e.g. 502 after commit), and attempt N sees the version already there.
  • Each attempt is wrapped in ::group:: / ::endgroup:: so the per-attempt logs are collapsible in the GH Actions UI.

If the workflow fails after all retries:

  1. Rerun the job from the GH Actions UI (Actions → failed run → Re-run failed jobs).
  2. Do NOT bump the version. The same tag + version is safe to re-publish because both registries treat "version already exists" as idempotent in our retry logic — whichever one previously succeeded will short-circuit, and the one that failed will get a fresh attempt.

For manual publishes (emergencies only — prefer CI):

  • If npx ovsx publish ... fails with a 502, just retry the same command 2–3 times.
  • If vsce publish fails with a 5xx, same — retry. Auth errors (TF400813) mean the PAT is bad; don't retry, fix the token.

Verifying

After CI goes green:

Rollback

Both registries treat published versions as immutable. You cannot unpublish or replace a bad version — you can only publish a patch that supersedes it.

If a bad version ships:

  1. Fix the regression on a branch, open a PR, land it on main.
  2. Prepend a new ## X.Y.Z — <date> entry with a ### Fixed subsection to CHANGELOG.md (patch-bumping the version), open a PR, and merge. The metadata-sync workflow auto-commits the corresponding package.json bump as chore: release vX.Y.Z on the PR branch — same flow as a normal release.
  3. If the regression is severe enough to warrant pulling the listing, the Marketplace / Open VSX admin UIs each offer a per-version unlist (different from unpublish) — use that as a last resort; prefer shipping forward.

Rollback guidance

OIDC auth failures

If the Login to Azure or Verify Marketplace credential step fails on the first OIDC publish, check these in order:

  1. SP not added as Contributor on the Marketplace publisher. copilotkit-vscode-publish must be a member of the copilotkit publisher at https://marketplace.visualstudio.com/manage/publishers/copilotkit with the Contributor (or higher) role.
  2. Federated credential subject mismatch. The credential on the Entra app must have subject exactly repo:CopilotKit/vscode-extension:environment:production (case-sensitive, no trailing slash). The workflow's environment: production must match that subject byte-for-byte.
  3. Tenant conditional access policy blocking workload identities. The copilotkit.ai tenant may have CA policies that block service principals from non-corporate IPs. Check Entra → Security → Conditional Access and exclude the copilotkit-vscode-publish SP from any policy that filters on location.
  4. Missing permissions: id-token: write on the publish job. Without this, GitHub will not mint an OIDC token and azure/login@v2 will fail with "Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable".

Temporary rollback to PAT

VSCE_PAT is retained in the production environment secrets specifically as a rollback lever for this cutover window. To revert:

  1. Check out .github/workflows/publish-vscode-extension.yml, replace --azure-credential with --pat "$VSCE_PAT", and re-add the env: { VSCE_PAT: ${{ secrets.VSCE_PAT }} } block on the Publish to VS Code Marketplace step.
  2. Push. Ship the release. Debug OIDC out of band.

Retiring the PAT

Once OIDC publishing has been confirmed green in CI at least once, delete VSCE_PAT from the production environment. That commit — the one that removes the last Marketplace PAT from the pipeline — is the actual completion of this migration. Until then the PAT is still a live credential and still needs to be treated as one for rotation / incident response purposes.

Notes and future work

  • ADO PAT retirement (2026-12-01): Azure DevOps is sunsetting long-lived Marketplace PATs. This workflow has been migrated to OIDC / federated credentials ahead of that date; VSCE_PAT is retained only as a short-lived rollback lever (see above).
  • If a release needs to pin to a specific @copilotkit/* version, bump the dependency in package.json as part of the same PR that updates the CHANGELOG.

One-time setup (historical reference)

The following setup was completed during pipeline bootstrap (2026-04-21) and should not need to be redone. Documented here for disaster recovery / re-bootstrapping.

Prerequisites (one-time, maintainer)

Configuration lives in the production GitHub environment (repo → Settings → Environments → production), split between non-secret variables and secrets:

Environment variables (non-secret, consumed by azure/login@v2):

  • AZURE_CLIENT_ID — client ID of the copilotkit-vscode-publish Entra Service Principal.
  • AZURE_TENANT_ID — tenant ID for copilotkit.ai.
  • AZURE_SUBSCRIPTION_ID — subscription the SP is scoped into.

Environment secrets:

  • OVSX_PAT — Open VSX Personal Access Token (bot-owned, quarterly rotation). OIDC is not yet supported on Open VSX, so a PAT is still required here.
  • VSCE_PATretained as explicit rollback only. No longer referenced by the workflow; Marketplace auth is OIDC. Delete this secret once OIDC publishing has been confirmed green at least once in production (see Rollback guidance).
  • SLACK_WEBHOOK (optional) — webhook for the #oss-alerts release ping. Publish succeeds without it.

One-time Open VSX setup (first release only)

Open VSX requires claiming the namespace before the first publish:

  1. Maintainer signs up at https://open-vsx.org with their GitHub identity.

  2. Creates a personal access token at https://open-vsx.org/user-settings/tokens.

  3. Claims the publisher namespace (one-time, from any machine):

    npx --yes ovsx create-namespace copilotkit -p <token>
  4. Stores the token as OVSX_PAT in the production GH environment.

Once the namespace is claimed, subsequent CI publishes run unattended.