Building and releasing¶
Verify a download¶
Every release has a SHA256SUMS.txt file next to the installers. Compare
the checksum of the file you downloaded with the line for its name:
shasum -a 256 Termalith_0.5.0_aarch64.dmg # macOS
sha256sum Termalith_0.5.0_amd64.AppImage # Linux
Get-FileHash .\Termalith_0.5.0_x64-setup.exe # Windows (PowerShell)
Installers are not code-signed yet, so the checksum is the way to confirm that a file came from the release page unchanged.
Build from source¶
Requirements on every system: Git, Node.js 24 or newer (with Corepack, which
ships with Node), and Rust through rustup. The exact Rust version is pinned
in rust-toolchain.toml and installed automatically on first build; the
pnpm version is pinned in package.json.
| System | Extra requirements |
|---|---|
| macOS | Xcode Command Line Tools (xcode-select --install) |
| Windows | Visual Studio Build Tools with "Desktop development with C++"; WebView2 (included in Windows 11) |
| Linux (Debian/Ubuntu) | libwebkit2gtk-4.1-dev libgtk-3-dev librsvg2-dev libayatana-appindicator3-dev libssl-dev build-essential |
git clone https://github.com/mehaskari/Termalith.git
cd Termalith
corepack pnpm install --frozen-lockfile
corepack pnpm --filter @termalith/desktop tauri build
The app is written to target/release/bundle/ (on macOS
target/release/bundle/macos/Termalith.app). corepack pnpm dev runs it
in development mode.
Checks run in CI on every pull request:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace
cargo deny check
corepack pnpm typecheck
corepack pnpm test
Make a release¶
Releases are built by the Release builds workflow on native GitHub
runners for macOS (Apple Silicon, Intel), Windows (x64, ARM64) and Linux
(x64, ARM64). Builds are reproducible from the tag: Rust, pnpm and every
dependency are pinned (rust-toolchain.toml, Cargo.lock,
pnpm-lock.yaml), and the workflow actions are pinned to commits.
- Make sure
mainis green in CI. - Set the version in
Cargo.toml(workspace),apps/desktop/package.jsonandapps/desktop/src-tauri/tauri.conf.json. - Move the Unreleased entries in the changelog under the new version.
- If dependencies changed, regenerate the license notices with
scripts/third-party-licenses.sh. - Merge, then tag the merge commit and push the tag:
git tag v0.5.0 && git push origin v0.5.0. - The workflow builds every installer and creates a draft GitHub
Release with the installers and
SHA256SUMS.txt. Tags with a suffix (v0.5.0-rc.4) become pre-releases; plain tags (v0.5.0) do not. - Install at least the builds you can test, check the release notes, then publish the draft.
Code signing (Apple Developer ID with notarization, a Windows code-signing certificate) and automatic updates are not set up yet. The app's Check for updates compares the running version with the latest published release and links to it; it never downloads or installs anything by itself.
Keeping the documentation current¶
The user guide (website/docs/guide/), the README and the changelog are
part of every change, and CI enforces it. scripts/check-docs.py runs in the
required cargo-deny job on every pull request and on main, and fails
when:
- the version differs between
Cargo.toml,apps/desktop/package.json,apps/desktop/src-tauri/tauri.conf.jsonand the website's landing page, or the changelog has no entry for it; - a setting in the Settings dialog is not described in
guide/settings.md, or a session type in the session dialog is missing fromguide/sessions.md; - a guide page is not in the site navigation, or links to a page or image that does not exist;
- a pull request changes user-facing code (
apps/desktop/src/,apps/desktop/src-tauri/src/) without touching the guide, the changelog or the README. If users really see no difference, add the labelno-docs-neededbefore pushing, or write[no docs]in a commit message.
The website build (mkdocs build --strict) fails on broken links, and
download links on the website and in the README point to the latest release
instead of a version number, so they never go stale.
Screenshots come from the UI mock and can be regenerated after UI changes:
corepack pnpm --filter @termalith/desktop dev # serves the mock on :1420
node scripts/docs-screenshots.mjs # Chrome required, no npm packages
python3 scripts/optimize-screenshots.py # optional, needs Pillow
Run locally before pushing: python3 scripts/check-docs.py --base origin/main.