| name | release-process |
| description | Release pipeline knowledge covering the stable release flow (release.yml -> post-release.yml -> release-sync.yml), the manual pre-release/RC flow (prerelease.yml), branch-naming to version-bump mapping, and NPM/GHCR publishing. Use when cutting a release, verifying a completed release, or troubleshooting the release pipeline. |
Release Process Skill
Overview
Lichtblick has two release tracks:
- Stable releases — triggered automatically when a merged pull request into
main comes from a release/* or hotfix/* branch. This runs .github/workflows/release.yml, which creates the GitHub Release and then fan-outs into post-release publishing and main→develop sync via GitHub's release: released event.
- Manual pre-release / RC builds — triggered manually through
.github/workflows/prerelease.yml (workflow_dispatch only). This builds the same production artifacts and, when create_release: true, creates a GitHub Pre-release through ncipollo/release-action with prerelease: true. Because GitHub's release event fires prereleased (not released) for pre-releases, this does not trigger post-release.yml or release-sync.yml — RC builds are never auto-published to NPM/GHCR or auto-synced to develop.
The stable and RC flows share the same artifact packaging shape, but only the stable flow performs the in-repo version bump, commit, and tag push to main.
Branch Naming -> Version Bump Mapping
The version bump is computed by regex in the bump_type step of .github/workflows/release.yml.
| Branch prefix pattern | Bump type | Example |
|---|
hotfix/* | patch | hotfix/fix-crash |
release/major or release/major/* | major | release/major/v2.0.0 |
release/minor or release/minor/* | minor | release/minor/v1.5.0 |
Any other branch prefix causes the workflow to fail with an explicit error.
Stable Release Pipeline (release.yml)
Trigger condition:
on:
pull_request:
types: [closed]
branches:
- main
jobs:
release:
if: |
github.event.pull_request.merged == true &&
(startsWith(github.head_ref, 'release/') || startsWith(github.head_ref, 'hotfix/'))
Step order:
- Check out the repository on
main.
- Set up Node.js 24 and enable Yarn via Corepack.
- Install dependencies with
yarn install --immutable.
- Determine the bump type from the source branch name:
hotfix/* -> patch
release/major(/.*)? -> major
release/minor(/.*)? -> minor
- anything else -> fail
- Bump the root version with
yarn version <type>.
- Bump
packages/suite/package.json with yarn version <type>.
- Read the new version from the root
package.json.
- Update
sonar-project.properties so sonar.projectVersion matches the new version.
- Commit the version files and tag
main as v${version}, then push main and tags.
- Build the production desktop and web bundles:
yarn desktop:build:prod
yarn web:build:prod
- Package release binaries for Windows, Linux, and macOS:
yarn package:win
yarn package:linux
yarn package:darwin
- Create the web static tarball at
dist/lichtblick-web.tar.gz.
- Create the GitHub Release with
ncipollo/release-action@v1.
- Trigger
sonarqube.yml on main via gh workflow run.
Release artifacts:
dist/lichtblick-${version}-linux-amd64.deb
dist/lichtblick-${version}-linux-x64.tar.gz
dist/lichtblick-${version}-linux-arm64.deb
dist/lichtblick-${version}-linux-arm64.tar.gz
dist/lichtblick-${version}-mac-universal.dmg
dist/lichtblick-${version}-win.exe
dist/lichtblick-web.tar.gz
dist/latest-linux.yml
dist/latest-mac.yml
dist/latest.yml
Post-Release Publishing (post-release.yml)
Trigger:
release: types: [released] — fires only for full (non-prerelease) GitHub Releases; pre-releases fire GitHub's separate prereleased event, which this workflow does not listen for.
- manual
workflow_dispatch — requires an explicit tag input (for example v1.28.1). Both jobs use github.event.inputs.tag || github.event.release.tag_name for the checkout ref and Docker version tagging, so a manual run publishes the specified tag instead of depending on release-event context.
This workflow fans out into two parallel jobs:
npm
Yarn (per the packageManager field in package.json, currently 4.17.0) via Corepack remains this repo's dependency manager everywhere else; npm publish here is an intentional, pipeline-only exception used solely to publish the built package to the npm registry.
- Check out the release tag (
github.event.release.tag_name).
- Set up Node.js 24 and point npm at
https://registry.npmjs.org.
- Enable Yarn and run
yarn install --immutable.
- Publish
./packages/suite to npm with npm publish ./packages/suite.
docker
- Check out the same release tag.
- Set up QEMU and Docker Buildx.
- Log in to GHCR.
- Strip the leading
v from the release tag for the versioned container tag.
- Build and push a multi-arch image for
linux/amd64,linux/arm64.
- Push both:
ghcr.io/<repo>:latest
ghcr.io/<repo>:<version-without-v-prefix>
Release Sync (release-sync.yml)
Trigger:
release: types: [released] — same caveat as post-release.yml: pre-releases fire prereleased, not released, so this workflow does not run for RC builds.
- manual
workflow_dispatch
This workflow keeps develop descended from main after a release:
- Check out
main with full history.
- Read the released version from
package.json.
- Create
sync/main-to-develop-{version} from origin/develop.
- Attempt
git merge origin/main --no-ff.
Two paths follow:
- Clean merge — push the sync branch, open a PR into
develop, and enable auto-merge with gh pr merge --merge --auto.
- Conflicted merge — commit the conflict markers, push the branch, and open a PR whose body warns that conflicts must be resolved manually.
In both cases, the workflow emphasizes the same rule: merge the sync PR with a MERGE COMMIT only — never squash or rebase — so main remains an ancestor of develop.
Manual Pre-release / RC Flow (prerelease.yml)
This workflow is manual-only (workflow_dispatch).
| Input | Type / options | Default | Purpose |
|---|
branch | choice (fixed dropdown values): develop, release/* | develop | Branch to build the pre-release from |
version_type | choice: prerelease, prepatch, preminor, premajor | prerelease | How to compute the next RC version |
create_release | boolean | true | Whether to publish a GitHub Pre-release |
release_notes | string | none | Optional custom release notes body |
Note: release/* is a literal option string in the workflow's choice input, not a wildcard/glob pattern. Selecting it only works if a branch is literally named release/*; to build an RC from an actual release branch (e.g. release/minor/v1.5.0), that exact branch name would need to be added as its own choice option (or the input changed to a free-text string type).
Version computation logic:
- Check out the selected branch with full history.
- Find the latest RC tag matching
v*rc.*.
- Compute the next version:
- If
version_type == "prerelease":
- with no RC tag yet:
semver.inc(baseVersion, "prerelease", "rc")
- with an existing RC tag:
semver.inc(lastRcWithoutLeadingV, "prerelease", "rc")
- Otherwise:
- derive a stable base version from
package.json
- run
semver.inc(stableBase, version_type, "rc")
- Use the computed version for artifact naming and release metadata.
Build and release steps:
- Build production desktop and web bundles.
- Package Windows, Linux, and macOS artifacts using
--config.extraMetadata.version=${version}.
- Create
dist/lichtblick-web.tar.gz.
- If
create_release == true, create a GitHub Pre-release with ncipollo/release-action@v1, prerelease: true, and the same artifact list as the stable release flow.
Note: This flow does not commit a version bump into git history. As covered above, GitHub fires prereleased (not released) for pre-releases, so post-release.yml and release-sync.yml do not run automatically after this workflow creates a GitHub Pre-release — NPM publishing, the GHCR image push, and the develop-sync PR only happen for stable releases.
Workflow Trigger Reference
| Workflow file | Trigger | Jobs |
|---|
.github/workflows/release.yml | pull_request closed on main, gated to merged PRs whose head branch starts with release/ or hotfix/ | release |
.github/workflows/post-release.yml | release: released (excludes pre-releases) or workflow_dispatch (requires tag input) | npm, docker |
.github/workflows/prerelease.yml | workflow_dispatch | prerelease |
.github/workflows/release-sync.yml | release: released (excludes pre-releases) or workflow_dispatch | sync |
Key Files
.github/workflows/release.yml
.github/workflows/post-release.yml
.github/workflows/prerelease.yml
.github/workflows/release-sync.yml