Thunderbolt Release Process: How to Publish New Versions Automatically
Thunderbolt’s release process is fully automated through GitHub Actions, where a single workflow trigger updates version files, creates signed tags, builds cross-platform binaries, and publishes distributable artefacts to GitHub, TestFlight, and the Google Play Store.
The Thunderbird Thunderbolt repository uses a modern CI/CD pipeline to manage its multi-platform desktop and mobile releases. Understanding the release process for publishing new versions of Thunderbolt helps contributors and maintainers ship updates safely without manual build steps or version drift across platform-specific configuration files.
Overview of the Automated Release Pipeline
Thunderbolt’s release orchestration lives entirely in GitHub Actions. The pipeline guarantees that version numbers remain consistent across JavaScript, Rust, and mobile-native manifests while producing signed, notarized binaries for every supported platform.
Three entry points control the release flow:
.github/workflows/release.yml– The primary production pipeline that executes the full build and publish cycle..github/workflows/version-bump.yml– A helper workflow that mutatespackage.json,Cargo.toml, andtauri.conf.jsonbefore tagging.scripts/create-release.ts– A local TypeScript CLI for dry-running version bumps or pushing tags manually.
Step-by-Step Release Workflow
The Thunderbolt release process proceeds through six deterministic phases, each enforced by the release.yml workflow.
1. Version Bump and File Synchronization
The pipeline first updates the canonical version identifier across the codebase. In scripts/create-release.ts (lines 38‑41), the script writes the new semver string to:
package.json(Node.js frontend)src-tauri/Cargo.toml(Rust core)src-tauri/tauri.conf.json(Tauri configuration)
This ensures that desktop, iOS, and Android builds reference identical version metadata.
2. Commit and Signed Tag Creation
After file mutations, the workflow commits the changes and creates an annotated Git tag. The implementation in scripts/create-release.ts (lines 40‑44) generates a tag in the format v{major}.{minor}.{patch} and pushes it to the remote repository. This tag acts as the immutable trigger for downstream build jobs.
3. Draft GitHub Release Generation
Upon tag detection, release.yml (lines 24‑27) initializes a draft GitHub release pre-populated with an auto-generated changelog. The draft state allows maintainers to review release notes before public visibility while the build matrix executes.
4. Parallel Cross-Platform Builds
The workflow fans out into platform-specific jobs that execute concurrently:
- Desktop – Tauri builds Linux (AppImage), macOS (Intel and Apple Silicon universal binaries), and Windows (x64 and ARM64 installers) with automatic code signing and notarization.
- iOS – The pipeline updates
src-tauri/gen/apple/project.yml, compiles a.ipa, and uploads to TestFlight via the App Store Connect API. - Android – The build computes a monotonic
versionCodeasBASE_OFFSET + git rev-list --count HEAD, constructs an.aab(Android App Bundle), and publishes to the Google Play Store Internal track.
Platform-specific version identifiers are injected at build time without committing transient changes to the repository.
5. Artefact Publication and Store Distribution
After successful builds, release.yml (lines 44‑47) attaches all desktop binaries to the GitHub release assets. Simultaneously, the iOS and Android workflows dispatch the signed mobile packages to their respective distribution channels, completing the end-to-end delivery pipeline.
6. Post-Release Validation
A final validation job in release.yml (lines 22‑26) asserts that the Git tag version matches the contents of package.json, Cargo.toml, and tauri.conf.json. If any mismatch is detected, the workflow fails fast to prevent shipping inconsistent version metadata.
Triggering a Thunderbolt Release
Maintainers can initiate the release process through three methods, ordered by recommendation.
GitHub Actions (Recommended)
Use the GitHub CLI to trigger the workflow with explicit parameters:
# Auto-detect version bump from commit history
gh workflow run release.yml -f version_type=auto
# Explicit semver
gh workflow run release.yml -f version=1.2.3
# Bump specific segment (major, minor, or patch)
gh workflow run release.yml -f version_type=minor
Local Helper Script
For testing or offline validation, the TypeScript CLI in scripts/create-release.ts supports dry-runs and local execution:
# Preview changes without modifying git state
bun run scripts/create-release.ts --dry-run
# Execute bump and push tag to trigger CI
bun run scripts/create-release.ts --push
# Force specific version locally
bun run scripts/create-release.ts --version 1.2.3 --push
Manual Method
While not recommended, maintainers can manually edit the four version files (package.json, src-tauri/Cargo.toml, src-tauri/tauri.conf.json), commit the changes, and push a tag matching the pattern v*.*.*. The release.yml workflow will still execute automatically upon tag detection.
Platform-Specific Version Management
Thunderbolt maintains platform-specific versioning semantics to satisfy store requirements while preserving a unified source of truth.
- Desktop (Tauri) – The version string in
src-tauri/tauri.conf.jsonacts as the canonical reference. The Tauri CLI propagates this value toCargo.tomland the Node environment during the build. - iOS – The
project.ymlfile insrc-tauri/gen/apple/receives the version string during the iOS build job. This transient modification is not committed to the repository. - Android – The
versionCodeis computed dynamically asBASE_OFFSET + git rev-list --count HEADto ensure monotonicity for the Google Play Store. Thetauri.propertiesfile insrc-tauri/gen/android/app/is auto-generated by the Tauri CLI and should never be edited manually.
Key Files in the Thunderbolt Release Process
| Path | Role |
|---|---|
.github/workflows/release.yml |
Orchestrates the full multi-platform release, including builds, signing, and store uploads. |
.github/workflows/version-bump.yml |
Helper workflow that mutates version files and creates annotated Git tags. |
scripts/create-release.ts |
TypeScript CLI for local version bumping, dry-runs, and optional git push. |
package.json |
Node.js frontend manifest; receives the new semver during the bump phase. |
src-tauri/Cargo.toml |
Rust backend manifest; synchronized with the canonical version. |
src-tauri/tauri.conf.json |
Source of truth for application version and Android versionCode base. |
src-tauri/gen/apple/project.yml |
iOS project configuration; updated transiently during the iOS build job. |
src-tauri/gen/android/app/tauri.properties |
Auto-generated Android properties; updated by Tauri CLI during builds. |
RELEASE.md |
Human-readable documentation describing the release process and emergency procedures. |
Summary
- Thunderbolt’s release process is fully automated via GitHub Actions, requiring only a single trigger to generate cross-platform binaries and mobile store uploads.
- Three entry points control the workflow:
.github/workflows/release.ymlfor production releases,.github/workflows/version-bump.ymlfor file mutations, andscripts/create-release.tsfor local testing. - Version consistency is enforced by a post-release validation job that confirms the Git tag matches
package.json,Cargo.toml, andtauri.conf.json. - Mobile platform versioning uses transient modifications to
project.yml(iOS) and dynamicversionCodecalculation (Android) to satisfy store requirements without polluting the git history.
Frequently Asked Questions
How do I trigger a Thunderbolt release from the command line?
Use the GitHub CLI to dispatch the release.yml workflow with the appropriate version parameter. For automatic versioning based on commit history, run gh workflow run release.yml -f version_type=auto. To specify an exact version, use gh workflow run release.yml -f version=1.2.3. Alternatively, run bun run scripts/create-release.ts --push locally to bump files and push a tag that triggers the same pipeline.
What files does the version bump update?
The version bump modifies three canonical files to maintain consistency across the Node.js frontend, Rust backend, and Tauri configuration: package.json (Node.js), src-tauri/Cargo.toml (Rust), and src-tauri/tauri.conf.json (Tauri source of truth). The workflow does not commit transient platform-specific files like src-tauri/gen/apple/project.yml or src-tauri/gen/android/app/tauri.properties, as these are generated during the build process.
Can I test the release process without creating a real tag?
Yes. Run the local helper script with the --dry-run flag: bun run scripts/create-release.ts --dry-run. This executes the version bump logic and displays the proposed changes to package.json, Cargo.toml, and tauri.conf.json without committing to git or pushing a tag. You can also review the workflow outputs in the GitHub Actions tab after pushing to a feature branch, as the release.yml logic only executes fully on tag pushes.
How does Thunderbolt handle version numbers for mobile platforms?
Thunderbolt uses platform-specific strategies to satisfy store requirements while keeping a single source of truth in tauri.conf.json. For iOS, the build pipeline transiently updates src-tauri/gen/apple/project.yml during the workflow without committing the change. For Android, the pipeline calculates a monotonic versionCode using the formula BASE_OFFSET + git rev-list --count HEAD, ensuring the Google Play Store receives incrementing version codes even when the semantic version jumps. The tauri.properties file is auto-generated by the Tauri CLI during the Android build and should never be edited manually.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →