Skip to content

Latest commit

 

History

History
151 lines (102 loc) · 6.9 KB

File metadata and controls

151 lines (102 loc) · 6.9 KB

Release Process

This repository publishes desktop releases from Git tags via GitHub Actions.

Tag convention

  • Final release: vMAJOR.MINOR.PATCH (example: v1.2.3)
  • Pre-release: vMAJOR.MINOR.PATCH-<prerelease> (example: v1.2.3-rc.1, v0.1.0-beta.11)
  • Accepted prerelease token format: dot-separated [0-9A-Za-z-]+ parts.

Validation regex in workflow:

^v([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$

Rules:

  • If the tag has no suffix (v1.2.3), GitHub release is published as final (prerelease: false).
  • If the tag contains a suffix (v1.2.3-beta.1, v1.2.3-rc.1, ...), GitHub release is published as prerelease (prerelease: true).

Build and publish workflow

Workflow file: .github/workflows/release.yml

Trigger:

  • Push tag matching v*

Pipeline order:

  1. Validate tag — SemVer format and prerelease flag.
  2. Test (Ubuntu only)npm test (Vitest) and cargo test in apps/desktop/src-tauri. If this job fails, no platform builds or GitHub release are produced.
  3. Build matrix — only runs after tests pass.

Build matrix:

  • ubuntu-latest
  • macos-latest
  • windows-latest

For each platform:

  1. Checkout repository.
  2. Setup Node.js and Rust toolchain.
  3. Install Linux build dependencies (Linux only).
  4. Install npm dependencies (apps/desktop).
  5. Sync app version from tag into:
    • apps/desktop/package.json
    • apps/desktop/src-tauri/tauri.conf.json
    • apps/desktop/src-tauri/Cargo.toml
    • (Not rewritten by CI — keep in sync locally when you prepare a release PR: apps/desktop/package-lock.json top-level version fields, and apps/desktop/src-tauri/Cargo.lock [[package]] name = "src-tauri" version line.)
  6. Run npm run tauri:build with optional NOSUCKSHELL_LICENSE_PUBKEY_HEX (64 hex chars) in the environment so the binary embeds your production Ed25519 verify key at compile time (option_env! in apps/desktop/src-tauri/src/license.rs).
  7. Upload generated bundles as build artifacts.

Production license public key (GitHub Actions)

For official release binaries, configure a repository secret:

  • Name: NOSUCKSHELL_LICENSE_PUBKEY_HEX
  • Value: 64-character hex string (32-byte Ed25519 public key) matching your deployed LICENSE_SIGNING_SEED_HEX.

The release workflow passes this secret into the Tauri build step. If the secret is missing (for example on a fork), builds still succeed but use the development verify key—fine for experimentation, not for selling tokens to end users.

Local release-style build:

export NOSUCKSHELL_LICENSE_PUBKEY_HEX="<your-64-hex-public-key>"
cd apps/desktop && npm run tauri:build

Release job:

  1. Download all uploaded platform artifacts.
  2. Create GitHub release for the tag.
  3. Mark release as final/prerelease based on parsed tag.
  4. Attach all built artifacts to the release.

AUR (nosuckshell-bin)

When a GitHub Release is published (not only tag push), .github/workflows/aur-publish.yml can update the AUR package nosuckshell-bin using aur/nosuckshell-bin/PKGBUILD. It runs only on the upstream repository d0dg3r/NoSuckShell and requires the AUR_SSH_PRIVATE_KEY repository secret (SSH key with push access to the AUR). See aur/README.md for one-time setup.

Creating a release

Create and push a tag:

# final release
git tag v0.2.0
git push origin v0.2.0

# prerelease
git tag v0.3.0-rc.1
git push origin v0.3.0-rc.1

# stable release (example: current product line)
git tag v0.2.1
git push origin v0.2.1

Current release (0.3.x)

  • Target tag: v0.3.5 — push when you are ready; in-repo versions in apps/desktop/package.json, apps/desktop/package-lock.json, apps/desktop/src-tauri/tauri.conf.json, and apps/desktop/src-tauri/Cargo.toml must match before you tag (see CHANGELOG.md).

  • What ships: see CHANGELOG.md for 0.3.5.

  • The release workflow still overwrites those files from the tag at build time; keeping them in sync avoids drift before the tag lands.

  • Working-tree drift: if package.json is bumped ahead of Cargo.toml / tauri.conf.json (or the reverse), realign before you cut a release so local tauri dev and CI agree on the product version.

Common pitfalls checklist

  • Ensure workflow has permissions: contents: write (required for release upload).
  • Ensure Linux runner installs Tauri system dependencies.
  • Keep version source single: tag is the source of truth.
  • Use tag-based trigger only (avoid releasing on every commit).
  • Keep asset names/platform artifacts separated by matrix job.
  • Keep workflow concurrency enabled to prevent duplicate runs for the same tag.

Follow-up: code signing and notarization

Current workflow builds and publishes unsigned artifacts. For production distribution, add platform signing:

  • Windows:
    • Sign .exe/.msi with a trusted code-signing certificate.
    • Store certificate material and passwords in GitHub Secrets.
  • macOS:
    • Sign app with Apple Developer ID certificate.
    • Notarize with Apple notary service.
    • Staple notarization ticket to distributables (.app/.dmg).
  • Linux:
    • AppImage generally works unsigned, but optional signature/provenance can be added in a hardened pipeline.

AppImage and host shared libraries (libpcre2 / libgit2)

Some rolling distros ship libgit2 that expects a version-tagged libpcre2 from the system. The AppImage bundles its own libpcre2 under the mount (/tmp/.mount_*/usr/lib/...). If anything in your environment puts that mount on the library search path while a host binary loads /usr/lib/libgit2.so.*, the dynamic linker can mix host libgit2 + AppImage libpcre2, which triggers warnings such as:

no version information available (required by /usr/lib/libgit2.so.*)

Typical triggers:

  • LD_LIBRARY_PATH (or similar) still containing the AppImage mount in a shell where you run git-aware tools (for example eza / exa / lsd aliased as ll).
  • Running those tools in the same environment while the AppImage payload is mounted.

Mitigations:

  • Prefer the native Arch package (.pkg.tar.zst from CI) on Arch-based systems when you hit this; it avoids AppImage library injection.
  • Use a clean shell without AppImage paths in LD_LIBRARY_PATH for unrelated CLI tools.
  • Official release AppImages are post-processed in CI to remove bundled libpcre2-8 so the loader can pick the system libpcre2 that matches your distro’s libgit2 (see scripts/postprocess-linux-appimage-libs.sh).

Recommended next step:

  1. Add secrets for signing credentials.
  2. Add conditional signing steps in .github/workflows/release.yml.
  3. Verify signed artifacts on each platform before public rollout.