Release process
How firmware releases and the @canshift/core npm package are cut in the per-repo layout.
import { Aside, Steps } from “@astrojs/starlight/components”;
Firmware releases ship from
CANShift/canshift-firmware.
This docs site pulls those GitHub Releases at build time and renders the
public changelog, so release descriptions need to be
substantive. The other repositories version and ship independently — there is
no global lockstep.
What ships from where
Section titled “What ships from where”- Firmware — GitHub Releases on
canshift-firmware, with signed binaries attached. This is the release stream the changelog renders. @canshift/core— published to npm. TaggingvX.Y.Zoncanshift-coreruns the publish workflow, which ships to npm with provenance. The npm version is independent of the schema version.- Tuner — deployed continuously by Vercel (preview per PR, production on
main). No release tag; whatever is onmainis live. - Mobile — store builds via EAS when it comes out of deferral. Not part of the firmware release stream.
Versioning
Section titled “Versioning”- Firmware:
canshift-firmware/package.json::version— the build bakes it intoAPP_VERSION_STR. Semver; still pre-1.0. - Core schema:
CURRENT_SCHEMA_VERSIONincanshift-core— bumped only when the config shape changes in a way the firmware must reject old configs for, always paired with a migration insrc/migrations/registry.tsin the same PR. Independent of both firmware semver and the@canshift/corenpm version. The firmware pins the schema version it expects incore-schema-version.txt— update that pin on every bump. - Core npm package:
canshift-core/package.json::version— bumped when you want consumers to be able to pull new contracts. Independent of the schema version.
The firmware semver bumps the most often. The schema version is the gate that forces a re-burn from the tuner.
Release-notes structure
Section titled “Release-notes structure”Every firmware release description follows this template (also documented in Changelog):
## [Version] — YYYY-MM-DD
### 🚗 For the driver
- (UX, new widgets, hardware support, etc.)
### 🔧 For the tuner / installer
- (config, calibration, ECU parameters)
### 🔬 Firmware / dev
- (build flags, schema, Rust modules, refactors)
### ⚠️ Breaking
- (concrete impact + required action — re-flash, re-burn config, etc.)
### PRs
- #XX — ...Cutting a firmware release
Section titled “Cutting a firmware release”The release is driven by merging a version bump — the workflow does the tagging and building. You are not tagging by hand.
-
Bump the firmware version in
canshift-firmware/package.json. Open a PR titledchore: bump to <version>and merge it tomain. -
Bump the schema version first, in a separate
canshift-corePR, if any breaking change to the config shape landed since the last release — pair it with a migration and updatecore-schema-version.txtin the firmware. Otherwise leave it alone. -
Let the release workflow run. On the version-bump merge, the workflow tags the commit, builds the signed firmware artifacts (merged / firmware / SPIFFS), and drafts a GitHub Release for the tag.
-
Fill in the release notes. Edit the drafted release, paste the structured template above, and write real content from the PR stream since the previous release. Then publish it.
-
Confirm the flasher sees it. The tuner’s Firmware view reads the GitHub Releases API on
canshift-firmwareand lists available versions — the new release appears there within about a minute. -
Smoke-test by re-flashing a dash from the tuner using the new release.
Patch vs minor vs major
Section titled “Patch vs minor vs major”- Patch (x.y.z → x.y.z+1): bug fix, no UX change, no schema change. Re-flash is optional unless the user hit the bug.
- Minor (x.y → x.y+1): new feature, no breaking change. Re-flash recommended.
- Major (breaking): driver MUST re-flash AND re-burn config. Spell out the
migration in the
⚠️ Breakingsection.
Pre-releases
Section titled “Pre-releases”Bump to a version with a pre-release suffix (e.g. 1.3.0-rc.1). GitHub
Releases recognises the suffix and badges it as “pre-release”; the tuner’s
Firmware view lists pre-releases behind a toggle.
Publishing @canshift/core
Section titled “Publishing @canshift/core”Core is released separately from the firmware:
- Bump
canshift-core/package.json::versionand merge tomain. - Tag the release commit
vX.Y.Zand push the tag — the publish workflow ships the package to npm with provenance. - Bump the
@canshift/coredependency incanshift-tuner(andcanshift-mobilewhen active) to pick up the new contracts.