Releasing MetaFlow
August 4, 2026 · View on GitHub
Version lane model
VS Code Marketplace does not support semver prerelease suffixes (1.2.3-beta.1 style).
Use even/odd minor versions instead:
- Stable lane: even minor versions such as
0.2.0,0.2.1, and0.4.0 - Prerelease lane: odd minor versions such as
0.3.0and0.3.1
The --pre-release flag on vsce package and vsce publish marks the extension as prerelease
in the Marketplace UI. The version number alone is not enough.
Branch model
mainis the stable branch. Publish even-minor stable releases frommainonly.prereleaseis a temporary convergence branch for odd-minor preview releases.- Create
prereleasefrommainonly when you have release-ready work worth previewing. - Merge preview-bound
feature/*andfix/*branches intoprereleasewhile that lane is active. - Before shipping a stable even-minor release, merge
prereleaseback intomainso both branches point at the same release commit. - After the stable release ships, delete
prereleaseuntil the next preview cycle starts.
Release cycle
1. Start a prerelease cycle when needed
Create prerelease from the current main tip only when you have new work ready for preview distribution.
git checkout main
git pull
git checkout -b prerelease
git push -u origin prerelease
Keep main stable while the cycle is active. Merge release-ready feature work into prerelease, not main.
2. Add a changeset (in your feature branch)
npm run changeset
Choose bump type: patch for fixes, minor for features, major for breaking changes.
Commit the generated .changeset/*.md file with your changes.
3. Merge to the active release lane
When your feature branch PR merges into prerelease during a preview cycle, or into main
when no preview cycle is active, the Version Packages workflow
(.github/workflows/version-packages.yml) automatically opens a PR titled
chore(release): version packages.
Review and merge that PR. It bumps src/package.json, packages/engine/package.json,
and packages/cli/package.json in lockstep and creates provisional package changelog
entries. It does not own the root CHANGELOG.md and does not create the final stable
release notes.
4. Publish prereleases from prerelease
Once the version PR is merged and prerelease is green, go to:
Actions -> Release Extension -> Run workflow
Inputs:
| Input | Value |
|---|---|
channel | prerelease |
Run prerelease publishes from the prerelease branch only. The workflow rejects prerelease
publishes from any other branch and also verifies that the version has an odd minor number.
5. Converge back to main for stable release
When the preview cycle is ready to ship as a stable release:
-
Run the stable-promotion command on
prereleasewith the even-minor target:npm run release:prepare-stable -- --promote-version 0.6.0
The command moves Unreleased notes and the preceding odd-minor package
changelog entries into the stable 0.6.0 entry, aligns all workspace package
versions and lock entries, and leaves no Unreleased heading on the stable
candidate. Update the root CHANGELOG.md with the complete, readable change
history and add the curated user-facing release notes described below. Review
both as part of the release PR.
- Run
npm run release:check-stable -- --version 0.6.0and the full release gate. - Merge
prereleaseback intomain. - Confirm
mainandprereleasepoint at the same release commit. - Publish the stable release from
main. - Delete
prereleaseafter the stable release ships.
Stable publishes run from main only. The workflow rejects stable publishes from prerelease
and verifies that the version has an even minor number.
6. Publish stable
Once the convergence merge is on main and main is green, go to:
Actions -> Release Extension -> Run workflow
Inputs:
| Input | Value |
|---|---|
channel | stable |
The workflow:
- Rejects a stable release if its changelogs retain
Unreleasedor preceding prerelease-version headings - Packages the VSIX with the appropriate channel flag
- Waits for manual approval via the GitHub Environment (
productionorprerelease) - Publishes to VS Code Marketplace and Open VSX
- Creates the git tag
vX.Y.Z - Creates the GitHub Release with the VSIX attached
If Release Drafter has already created a draft for the version, the workflow uploads the VSIX and publishes that draft; a successful upload alone is not treated as a completed release.
For stable releases, the workflow uses the matching curated release-note file as the GitHub Release body. Do not rely on generated commit notes for a user-facing release announcement.
The tag is created after publish succeeds, so a failed gate never leaves a dangling tag.
Release-note policy
Release notes and changelogs serve different readers:
CHANGELOG.mdis the complete, human-readable history. It may group changes by Added, Changed, and Fixed and link to package-level detail.docs/releases/vX.Y.Z.mdis the canonical GitHub Release body for a stable version. It is a short product update for people deciding whether to install or update.
Create the release-note file before running a stable publish. npm run release:check-stable
requires it, and npm run release:notes -- --version X.Y.Z --output <path> copies it into the
GitHub Release workflow.
Write release notes in this order:
- A one-sentence plain-language summary of the release's value.
## Highlightswith three to five outcome-oriented bullets for the most important new or changed user capabilities.## Improvementsor## Fixesonly when they contain meaningful user-visible changes.## Before you updateonly for required actions, compatibility changes, migrations, or known limitations.
Use active, concrete language: “Package shared guidance as a Copilot plugin,” not an internal implementation description. Keep one user-visible outcome per bullet. Avoid commit IDs, CI, release mechanics, exhaustive implementation detail, and empty sections. A documentation-only release should say that behavior is unchanged and direct readers to the corrected feature release.
Branch invariants enforced by automation
prereleasechannel releases must run from theprereleasebranch.prereleasechannel releases must use an odd minor version.stablechannel releases must run frommainor arelease/*hotfix branch.stablechannel releases must use an even minor version.
Package scripts
All run from src/ (or npm -C src run <script> from the workspace root):
npm run typecheck # type-check without emitting
npm run package:stable # build stable VSIX → src/artifacts/
npm run package:pre # build prerelease VSIX → src/artifacts/
Prerelease vs stable packaging
| Script | vsce flag | Marketplace lane |
|---|---|---|
package:stable | (none) | Stable |
package:pre | --pre-release | Prerelease |
Users opt into the prerelease lane through the extension install UI in VS Code.
Both channels share the same extension identity (dynfxdigital.metaflow-ai).
Required setup
GitHub Environments
Create two environments in repository Settings → Environments:
| Environment name | Used for |
|---|---|
production | Stable channel releases |
prerelease | Prerelease channel releases |
Add required reviewers to each environment for a manual approval gate before publish.
Secrets
| Secret | Source |
|---|---|
VSCE_PAT | Azure DevOps personal access token, Marketplace (Manage) scope |
OVSX_PAT | Open VSX token from https://open-vsx.org/user-settings/tokens |
Keep secrets only in GitHub Actions secrets. Never commit tokens or paste them in issues/PRs. Rotate immediately if exposure is suspected.
Publisher membership
The account that owns VSCE_PAT must be a member of the dynfxdigital publisher.
A valid token without publisher membership is not sufficient.
Hotfix
- Create a
release/vX.Y.Zbranch from the last stable tag. - Apply the minimal fix. Run the gate.
- Trigger the stable publish workflow from that branch.
- Cherry-pick the fix to
main.
Hotfix branches publish stable releases only. Do not use a release/* branch for prerelease distribution.
Dependency and artifact hardening
- Publish the built VSIX (
--packagePath), not a freshvsce publishfrom source. - This extension depends on a local workspace package (
@metaflow/engineviafile:../packages/engine); a plainvsce publishcan bundle unexpected workspace content. - Before each release, verify VSIX contents and dependency graph.
- If a packaging step shows unexpected network access or new lifecycle scripts, stop the release, treat the environment as potentially compromised, and rotate secrets before rebuilding.