This document describes the automated release pipeline for the RocketRide Engine monorepo. All releases are driven by GitHub Actions workflows and require no manual artifact creation.
- Overview
- Packages
- Branching Strategy
- Nightly Prereleases
- Stable Releases
- Version Management
- Tags and GitHub Releases
- Registry Publishing
- Build Matrix
- Troubleshooting
The release pipeline consists of two workflows:
| Workflow | Trigger | Purpose |
|---|---|---|
Nightly (.github/workflows/nightly.yaml) |
Daily at 02:00 UTC or manual dispatch | Build and publish prereleases from stage |
Release (.github/workflows/release.yaml) |
Push to main |
Build, publish to registries, and create stable GitHub Releases |
Both workflows build the full project across three platforms (Linux, Windows, macOS), run tests, and package artifacts. The key difference is that nightly creates prereleases on GitHub only, while the release workflow publishes to external registries (npm, PyPI, VS Code Marketplace) and creates stable GitHub Releases.
The monorepo produces five independently versioned and released packages:
| Package | Description | Version Source | Registry |
|---|---|---|---|
| Server | Core RocketRide engine binaries | package.json (root) |
GitHub Releases only |
| TypeScript Client | Node.js/browser SDK | packages/client-typescript/package.json |
npm |
| Python Client | Python SDK | packages/client-python/pyproject.toml |
PyPI |
| MCP Client | Model Context Protocol integration | packages/client-mcp/pyproject.toml |
PyPI |
| VS Code Extension | Visual Studio Code extension | apps/vscode/package.json |
VS Code Marketplace and Open VSX |
Each package produces specific artifacts during the build:
Server (per platform):
rocketride-server-v{version}-win64.zip— Windows x64 binary archiverocketride-server-v{version}-win64.symbols.zip— Windows debug symbolsrocketride-server-v{version}-win64.manifest.json— Build manifest with content hashrocketride-server-v{version}-linux-x64.tar.gz— Linux x64 binary archiverocketride-server-v{version}-linux-x64.manifest.json— Build manifestrocketride-server-v{version}-darwin-arm64.tar.gz— macOS ARM64 binary archiverocketride-server-v{version}-darwin-arm64.manifest.json— Build manifest
TypeScript Client:
rocketride-{version}.tgz— npm package tarball
Python Client:
rocketride-{version}-py3-none-any.whl— Python wheelrocketride-{version}.tar.gz— Python source distribution
MCP Client:
rocketride_mcp-{version}-py3-none-any.whl— Python wheelrocketride_mcp-{version}.tar.gz— Python source distribution
VS Code Extension:
rocketride-{version}.vsix— VS Code extension package
feature/* ──┐
bugfix/* ──┼──> develop ──> stage ──> main
hotfix/* ──┘ │ │
│ │
Nightly builds Stable releases
(prereleases) (registry + GitHub)
develop— Integration branch. All feature and bugfix branches merge here. No prereleases are built from this branch.stage— Prerelease stabilization branch. Changes are promoted fromdeveloptostageonce they are ready to be validated. Nightly prereleases are built from this branch, so a broken commit ondevelopcannot leak into a prerelease.main— Stable release branch. Whenstageis merged intomain, the release workflow triggers automatically.feature/*,bugfix/*,hotfix/*— Short-lived branches that merge intodevelopvia pull request.
Workflow: .github/workflows/nightly.yaml
Trigger: Runs automatically every day at 02:00 UTC, or can be triggered manually via GitHub Actions UI (workflow_dispatch).
-
Initialize — Extract current versions from all package files.
-
Build — Compile and test the full project on all three platforms in parallel:
- Ubuntu 22.04 (Linux x64)
- Windows Server 2022 (Windows x64)
- macOS 14 (ARM64)
-
Clean up previous prereleases — Delete all existing GitHub Releases and tags with the
-prereleasesuffix. This ensures stale prereleases from previous versions are removed. -
Create prereleases — Create five separate GitHub Releases, one per package, each marked as a prerelease:
GitHub Release Tag Prerelease -- Server {version} server-v{version}-prereleasePrerelease -- TypeScript Client {version} client-typescript-v{version}-prereleasePrerelease -- Python Client {version} client-python-v{version}-prereleasePrerelease -- MCP Client {version} client-mcp-v{version}-prereleasePrerelease -- VS Code Extension {version} vscode-v{version}-prerelease
- Prereleases are not published to any external registry (npm, PyPI, VS Code Marketplace). They are only available as downloadable artifacts on the GitHub Releases page.
- Each nightly run replaces the previous prerelease for the same version. There is only ever one prerelease per package version at any given time.
Visit the Releases page and look for releases tagged with -prerelease. These contain the latest builds from the stage branch.
Workflow: .github/workflows/release.yaml
Trigger: Automatically runs when commits are pushed to the main branch (typically via a merge from stage).
-
Initialize — Extract current versions from all package files.
-
Build — Compile and test the full project on all three platforms in parallel (same as nightly).
-
Publish — Each package is processed independently with
fail-fast: false, meaning one package failure does not block the others. For each package:a. Check if already released — If the git tag (e.g.,
server-v1.0.3) already exists, the package is skipped entirely. This makes the workflow fully idempotent.b. Publish to registry — Push the package to its external registry. Each registry publish includes a check to skip if the version already exists:
- TypeScript Client →
npm publishto npmjs.org - Python Client →
twine uploadto PyPI - MCP Client →
twine uploadto PyPI - VS Code Extension →
vsce publishto VS Code Marketplace andovsx publishto Open VSX - Server → No registry publish (binaries are distributed via GitHub Releases only)
c. Create git tag — Tag the commit (e.g.,
server-v1.0.3).d. Create GitHub Release — Create a GitHub Release with the tag, auto-generated release notes, and the package artifacts attached.
- TypeScript Client →
The release workflow is designed to be fully idempotent:
- If a git tag already exists for a package version, that package is skipped entirely — no registry publish, no GitHub Release creation.
- If a version already exists on a registry (npm, PyPI, Marketplace) but the git tag does not exist, the registry publish step is skipped but the GitHub Release is still created.
- Running the release workflow multiple times with the same versions produces the same result as running it once.
Each package is published independently:
- If the Python Client publish fails, the TypeScript Client, Server, and all other packages are unaffected.
- Partial failures can be resolved by fixing the issue and re-running the workflow (or pushing a new commit to
main). Already-published packages will be skipped automatically.
| Package | File | Field |
|---|---|---|
| Server | package.json (root) |
version |
| TypeScript Client | packages/client-typescript/package.json |
version |
| Python Client | packages/client-python/pyproject.toml |
project.version |
| MCP Client | packages/client-mcp/pyproject.toml |
project.version |
| VS Code Extension | apps/vscode/package.json |
version |
- Bump the version in the appropriate file(s) on the
developbranch. - Commit and push to
develop, then mergedevelopintostageonce the change is ready to be validated:The next nightly build will create a prerelease with the new version fromgit checkout stage git merge develop git push origin stage
stage. - Verify the prerelease by downloading artifacts from the GitHub Releases page.
- Merge
stageintomain:git checkout main git merge stage git push origin main
- The release workflow triggers automatically and publishes all packages with new versions.
Because each package is versioned independently, you can release a single package by bumping only its version. For example, to release a new TypeScript Client version without releasing the Server:
- Bump only
packages/client-typescript/package.json→version - Merge to
main - The release workflow creates a new
client-typescript-v{version}release; all other packages are skipped because their tags already exist.
- Follow Semantic Versioning (MAJOR.MINOR.PATCH).
- Bump MAJOR for breaking API changes.
- Bump MINOR for new features that are backward compatible.
- Bump PATCH for backward-compatible bug fixes.
| Type | Pattern | Example |
|---|---|---|
| Server stable | server-v{version} |
server-v1.0.3 |
| TypeScript Client stable | client-typescript-v{version} |
client-typescript-v1.0.1 |
| Python Client stable | client-python-v{version} |
client-python-v1.0.1 |
| MCP Client stable | client-mcp-v{version} |
client-mcp-v0.1.0 |
| VS Code stable | vscode-v{version} |
vscode-v0.0.1 |
| Server prerelease | server-v{version}-prerelease |
server-v1.0.3-prerelease |
| TypeScript Client prerelease | client-typescript-v{version}-prerelease |
client-typescript-v1.0.1-prerelease |
| Python Client prerelease | client-python-v{version}-prerelease |
client-python-v1.0.1-prerelease |
| MCP Client prerelease | client-mcp-v{version}-prerelease |
client-mcp-v0.1.0-prerelease |
| VS Code prerelease | vscode-v{version}-prerelease |
vscode-v0.0.1-prerelease |
- A
-prereleasetag is created (or force-updated) by the nightly workflow. - When the version is promoted to stable (merged to
main), a stable tag (without-prerelease) is created. - The next nightly run cleans up all
-prereleasetags and recreates them with the current versions.
- Package name:
rocketride - Registry: https://www.npmjs.com/package/rocketride
- Authentication:
NPM_TOKENsecret - Skip logic: Checks
npm view "rocketride@{version}" versionbefore publishing
- Package name:
rocketride - Registry: https://pypi.org/project/rocketride/
- Authentication:
PYPI_TOKENsecret - Skip logic: Checks
https://pypi.org/pypi/rocketride/{version}/jsonHTTP status before publishing
- Package name:
rocketride-mcp - Registry: https://pypi.org/project/rocketride-mcp/
- Authentication:
PYPI_TOKENsecret - Skip logic: Checks
https://pypi.org/pypi/rocketride-mcp/{version}/jsonHTTP status before publishing
- Package name:
rocketride - Registry: https://marketplace.visualstudio.com/
- Authentication:
VSCE_PATsecret - Skip logic: Catches "already exists" error from
vsce publish
- Package name:
rocketride - Registry: https://open-vsx.org/
- Authentication:
OVSX_PATsecret - Skip logic: Catches "already exists" error from
ovsx publish
Both workflows build on the same three platforms:
| Platform | Runner | Server artifact format |
|---|---|---|
| Linux x64 | ubuntu-22.04 |
.tar.gz |
| Windows x64 | windows-2022 |
.zip + .symbols.zip |
| macOS ARM64 | macos-14 |
.tar.gz |
Client packages (TypeScript, Python, MCP) and the VS Code extension are platform-independent and are built only on the Ubuntu runner.
- pnpm 10 — Package manager and workspace orchestration
- vcpkg — C++ dependency management with NuGet binary caching via GitHub Packages
- CMake + Ninja — C++ build system
- Node.js 20 — TypeScript compilation and npm publishing
- Python 3.12 — Python package building and PyPI publishing
This can happen if the workflow fails between the registry publish step and the GitHub Release creation step. To fix:
- The git tag was not created, so re-running the workflow (push a new commit to
mainor re-run the failed workflow) will retry. The registry publish will be skipped (version already exists) and the GitHub Release will be created.
This means the tag was created manually or by a previous version of the workflow. To fix:
- Delete the orphan tag:
git push origin --delete {tag-name} git tag -d {tag-name} - Re-run the release workflow. It will recreate the tag and the GitHub Release.
- Check that the workflow is enabled in the GitHub Actions UI (Settings > Actions > General).
- The nightly always runs on schedule — there is no commit-based skip logic.
- You can manually trigger it via the GitHub Actions UI using "Run workflow".
The release workflow skips a package if its git tag already exists. To check:
git tag -l '{package}-v{version}'If the tag exists and you need to re-release, delete the tag first (see "A git tag exists but there is no GitHub Release" above).
The following secrets must be configured in the release environment:
| Secret | Used for |
|---|---|
NPM_TOKEN |
Publishing to npm |
PYPI_TOKEN |
Publishing to PyPI |
VSCE_PAT |
Publishing to VS Code Marketplace |
OVSX_PAT |
Publishing to Open VSX |
Update these in GitHub Settings > Environments > release > Environment secrets.