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:

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:

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 versionCode as BASE_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.

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.json acts as the canonical reference. The Tauri CLI propagates this value to Cargo.toml and the Node environment during the build.
  • iOS – The project.yml file in src-tauri/gen/apple/ receives the version string during the iOS build job. This transient modification is not committed to the repository.
  • Android – The versionCode is computed dynamically as BASE_OFFSET + git rev-list --count HEAD to ensure monotonicity for the Google Play Store. The tauri.properties file in src-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.yml for production releases, .github/workflows/version-bump.yml for file mutations, and scripts/create-release.ts for local testing.
  • Version consistency is enforced by a post-release validation job that confirms the Git tag matches package.json, Cargo.toml, and tauri.conf.json.
  • Mobile platform versioning uses transient modifications to project.yml (iOS) and dynamic versionCode calculation (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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →