Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Latest commit

 

History

History
418 lines (306 loc) · 14.9 KB

File metadata and controls

418 lines (306 loc) · 14.9 KB

Release Process

Overview

ADM has three distributable components:

  1. Desktop application (Tauri 2 bundle) — the primary release artifact, includes the daemon sidecar and native host binary.
  2. Browser extension — maintained in a separate repository; released independently.
  3. Portable binariesadm, adm-daemon, adm-cli, adm-test-server for scripting/headless use.

All releases are created through the CI workflow (.github/workflows/release.yml) triggered by a v* tag push. Manual release via workflow_dispatch is also supported.

Current status: Pre-release (0.0.0-dev). No tagged releases exist yet. The release pipeline is implemented but requires validation before first use.


Versioning

Scheme

ADM follows Semantic Versioning (major.minor.patch) with optional pre-release suffixes:

Pattern Example Type
v0.0.0-dev v0.0.0-dev Development (untagged)
v0.1.0 v0.1.0 Stable release
v0.2.0-beta.1 v0.2.0-beta.1 Pre-release
v0.2.0-rc.1 v0.2.0-rc.1 Release candidate

Where Versions Live

File Value Source of Truth
Cargo.toml (workspace) 0.0.0-dev Yes — single source for Rust crates
apps/desktop-ui/package.json 0.0.0-dev Mirrors workspace via version.workspace (Cargo)
package.json (root) 0.0.0-dev Mirrors workspace
apps/desktop-ui/src-tauri/tauri.conf.json 0.0.0 Hardcoded; overridden at CI time by patch-tauri-ci-config.py
install.sh 0.2.0 Independent installer script version
install.ps1 0.2.0 Independent installer script version

Version Resolution

Version is resolved from git tag or CI environment in this order:

  1. ADM_RELEASE_VERSION environment variable
  2. GITHUB_REF_NAME (e.g., v0.1.0)
  3. Fallback: 0.0.0-dev

The version resolver lives in .github/scripts/release_version.py and produces:

ADM_VERSION_RAW=v0.1.0
ADM_VERSION_DISPLAY=0.1.0
ADM_VERSION_NUMERIC=0.1.0
ADM_VERSION_FILE=0.1.0.0
ADM_VERSION_IS_TAG=1
ADM_VERSION_IS_PRERELEASE=0

Changelog

A CHANGELOG.md file is required in the repository root. The CI quality gate validates its presence before proceeding with the release. The changelog must follow common conventions:

# Changelog

## [Unreleased]

### Added
- ...

### Changed
- ...

### Fixed
- ...

## [0.1.0] - 2026-01-15

### Added
- ...

Note: CHANGELOG.md does not currently exist in the repository. One must be created before the first tagged release or the CI release workflow will fail at the quality gate.


Build & Check Commands

Pre-Release Verification

Run these locally before tagging a release:

# 1. Full Rust compilation
cargo check --locked --workspace --all-targets

# 2. Lint
cargo clippy --locked --workspace --all-targets -- -D warnings

# 3. Format
cargo fmt --all --check

# 4. Download engine tests
cargo test --locked -p adm-download-engine

# 5. Full workspace tests
cargo test --locked --workspace --all-features

# 6. Security audit
cargo deny check
cargo audit

# 7. Desktop UI
pnpm install --frozen-lockfile
pnpm --filter @adm/desktop typecheck
pnpm --filter @adm/desktop lint
pnpm --filter @adm/desktop build

# 8. Desktop UI full Tauri build (produces bundle)
pnpm tauri build

CI Quality Gate

The CI quality job runs automatically on every tag push:

  • cargo fmt --check
  • cargo clippy -D warnings
  • cargo build --workspace --exclude adm-desktop
  • cargo test --workspace --exclude adm-desktop
  • cargo check -p adm-desktop
  • pnpm install --frozen-lockfile && pnpm --filter @adm/desktop build
  • cargo deny check
  • cargo audit
  • Validate repository release hygiene (CHANGELOG.md, CONTRIBUTING.md, LICENSE, README.md, .gitignore, .editorconfig, .gitattributes, dependabot.yml all present)

Artifact Generation

Build Matrix

The CI build job produces artifacts for 6 targets across 3 platforms:

Target Tier Arch OS Package Formats Portable Format
linux-x64 Required x86_64 Linux AppImage, deb, rpm tar.gz
linux-arm64 Experimental aarch64 Linux AppImage, deb, rpm tar.gz
windows-x64 Required x86_64 Windows NSIS (.exe), MSI zip
windows-arm64 Experimental aarch64 Windows NSIS (.exe), MSI zip
macos-x64 Required x86_64 macOS DMG, .app zip
macos-arm64 Required aarch64 macOS DMG, .app zip

Artifacts Per Target

Each target produces:

  1. Portable archive — Contains adm + adm-daemon + adm-cli + adm-test-server binaries
  2. Platform installer — Native bundle format for the OS
  3. SHA256 checksumSHA256SUMS.txt and per-file .sha256 files
  4. Tauri updater signature (if signing configured) — .sig file for the installer

Sidecar Staging

The daemon (adm-daemon) and CLI (adm-cli) are compiled as separate release binaries and staged into the Tauri bundle via stage-tauri-sidecars.mjs:

apps/desktop-ui/src-tauri/
  binaries/
    adm-daemon-x86_64-pc-windows-msvc.exe
    adm-daemon-x86_64-unknown-linux-gnu
    adm-daemon-aarch64-apple-darwin
    ...
  resources/
    adm-cli-x86_64-pc-windows-msvc.exe
    ...

The Tauri config references binaries/adm-daemon as an externalBin and resources/adm-cli* as a resource. Tauri locates the correct triple-qualified file at runtime.

Frontend Assets

The Vite/React frontend is built once in the frontend-assets CI job and shared across all build targets via GitHub Actions artifact upload/download.


Packaging

Tauri Bundle

Run from apps/desktop-ui/:

# Stage sidecars (builds daemon + CLI in release mode)
node scripts/stage-sidecars.mjs

# Build Tauri bundle
node scripts/tauri-cli.mjs build

The tauri-cli.mjs wrapper strips CARGO_BUILD_TARGET before invoking cargo tauri build to avoid cargo path conflicts.

Tauri tauri.conf.json bundle configuration:

Field Value
bundle.active true
bundle.targets "all"
bundle.category "Utility"
bundle.externalBin ["binaries/adm-daemon"]
bundle.resources ["resources/adm-cli*"]
bundle.windows.nsis.installMode "perMachine" (installs to %ProgramFiles%\APEX Download Manager, requires admin elevation)
bundle.windows.nsis.languages ["English", "Arabic"]
bundle.windows.nsis.installerHooks "./windows/installer-hooks.nsh" — kills adm.exe/adm-daemon.exe before install/uninstall and removes settings/logs/database directories on uninstall

Portable Binaries

Portable archives are collected after Tauri builds the desktop binary. They contain:

adm (or adm.exe)           # Tauri desktop shell (includes daemon sidecar)
adm-daemon (or .exe)       # Standalone daemon binary
adm-cli (or .exe)          # CLI client
adm-test-server (or .exe)  # Test HTTP server

Code Signing & Notarization

Windows

Implemented (installer/windows-sign-artifacts.ps1):

  • Signs .exe and .msi files using signtool.exe from Windows SDK
  • Algorithm: SHA256 (/fd SHA256)
  • Timestamp: RFC 3161 (/tr + /td SHA256)
  • Certificate source: WINDOWS_SIGNING_CERT_BASE64 or WINDOWS_SIGNING_CERT_PATH
  • Certificate password: WINDOWS_SIGNING_CERT_PASSWORD
  • Timestamp URL: WINDOWS_SIGNING_TIMESTAMP_URL (default: http://timestamp.digicert.com)

Signing runs twice in CI:

  1. Portable binaries (pattern: *.exe)
  2. Installers (patterns: *.exe, *.msi)

Prerequisites: Install Windows SDK (includes signtool.exe).

Tauri Updater Signing

Implemented (CI secrets):

  • Private key: TAURI_SIGNING_PRIVATE_KEY
  • Key password: TAURI_SIGNING_PRIVATE_KEY_PASSWORD
  • Public key: TAURI_UPDATER_PUBKEY
  • Updater is disabled by default in tauri.conf.json (active: false, pubkey: "")
  • CI enables it at build time via patch-tauri-ci-config.py when secrets are present
  • The release-metadata.py script validates that stable releases have .sig files

macOS Notarization

Not implemented. macOS targets use ad-hoc signing (APPLE_SIGNING_IDENTITY: "-" in CI). Notarization via xcrun notarytool would need to be added before distributing macOS builds outside a developer's direct control.


GitHub Release

The final CI job (release) creates a GitHub Release with:

  1. Release notes — Generated from CHANGELOG.md content for the version. Generated by .github/scripts/release-metadata.py.
  2. Artifacts — All installer bundles, portable archives, checksums, and updater metadata from all targets.
  3. Metadata files:
    • release-manifest.json — Full artifact listing with checksums and platform info
    • SHA256SUMS.txt + per-file .sha256 — Checksum verification
    • latest.json — Tauri updater metadata (only on stable releases with signatures)
    • release-notification.json — Webhook notification payload

Release Manifest Format

{
  "version": "0.1.0",
  "created_at": "2026-01-15T10:00:00Z",
  "artifacts": {
    "linux-x64": {
      "portable": { "filename": "adm-0.1.0-linux-x64.tar.gz", "sha256": "abc...", "size": 123456 },
      "package": { "filename": "adm_0.1.0_amd64.AppImage", "sha256": "def...", "size": 789012 }
    },
    "windows-x64": { ... },
    "macos-arm64": { ... }
  }
}

Post-Release Validation

After the release is published:

  1. Download and verify: Download the portable archive for your platform, verify SHA256 checksum.
  2. Run the daemon: ./adm-daemon — should start and listen on 127.0.0.1:57423.
  3. Run the CLI: ./adm-cli status — should show daemon is connected.
  4. Test downloads: Use the desktop UI or CLI to initiate a download.
  5. Check updater: If updater was enabled, verify the latest.json endpoint returns correct data.
  6. Test installer: Run the platform installer on a clean machine, verify sidecar is registered.
  7. Test browser integration: Install extension, verify pairing flow works.
  8. Verify signatures: On Windows, check digital signatures on .exe and .msi files.

Rollback Guidance

If a release has a critical bug

  1. Do not delete the release — GitHub Releases are permanent. Mark the release as "Pre-release" or draft a new release note with a warning.
  2. Create a patch release — Increment the patch version, fix the bug, tag v0.1.1.
  3. Update latest.json — The Tauri updater reads latest.json from the latest GitHub Release. Pointing to a fixed version is automatic if it's the newest tag.
  4. Notify distribution channels — Post a notice in the GitHub Release description.

If Tauri updater metadata is wrong

  • Update latest.json directly via the GitHub Releases API to point to the correct artifact.
  • The release-metadata.py script generates this; re-run with corrected version and upload.

Release Checklist

Before Tagging

  • All CI checks pass locally: cargo check, clippy, fmt, test
  • CHANGELOG.md exists and contains the release entry
  • All commits since last release are documented in changelog
  • cargo deny check and cargo audit pass with no yanked/unmaintained advisories
  • Desktop UI builds: pnpm typecheck && pnpm lint && pnpm build
  • No placeholder or dummy values in tauri.conf.json
  • Updater public key is configured (if applicable)
  • Windows signing certificate is available (if applicable)
  • Extension IDs for native host are set: ADM_CHROME_EXTENSION_ID, ADM_EDGE_EXTENSION_ID, ADM_FIREFOX_EXTENSION_ID
  • No placeholder extension IDs remain in production.rs (no REPLACE_WITH_* or <CHROME_WEB_STORE_ID>)
  • Test tag locally: git tag v0.1.0 && git push origin v0.1.0 and monitor CI

After Release

  • Verify GitHub Release was created with all expected artifacts
  • Download and verify SHA256 checksums
  • Smoke-test the portable archive on each platform
  • Test the installer on a clean machine (Windows NSIS/MSI, macOS DMG, Linux AppImage/deb/rpm)
  • Verify daemon starts from Tauri desktop shell
  • Verify browser extension can pair (via native host)
  • If updater enabled: verify latest.json is accessible and the app can detect the update
  • Update documentation if any release process steps changed

Environment Variables for Release Builds

Variable Required Purpose
ADM_RELEASE_VERSION For CI Override version (default: from git tag)
ADM_CHROME_EXTENSION_ID For native host Chrome Web Store extension ID
ADM_EDGE_EXTENSION_ID For native host Edge Add-ons extension ID
ADM_FIREFOX_EXTENSION_ID For native host Firefox Add-ons extension ID
WINDOWS_SIGNING_CERT_BASE64 For Windows signing Base64-encoded Authenticode certificate
WINDOWS_SIGNING_CERT_PASSWORD For Windows signing Certificate private key password
WINDOWS_SIGNING_TIMESTAMP_URL For Windows signing RFC 3161 timestamp server URL
TAURI_SIGNING_PRIVATE_KEY For updater Tauri updater private key
TAURI_SIGNING_PRIVATE_KEY_PASSWORD For updater Tauri updater key password
TAURI_UPDATER_PUBKEY For updater Tauri updater public key
APPLE_SIGNING_IDENTITY For macOS Code signing identity (currently "-" ad-hoc)

Runtime Assumptions for Release Builds

  • Rust: 1.96.0 (from rust-toolchain.toml), edition 2021
  • Node: 24+, pnpm: 11.8.0 (from packageManager field)
  • Tauri CLI: ^2.2.7 (from root devDependencies)
  • Cross-compilation: Not done in CI — each target builds natively on a platform-specific runner
  • Tauri bundler: Must be installed (cargo install tauri-cli --version "^2") or available via pnpm tauri (which invokes the local @tauri-apps/cli package)
  • Windows signing: Requires Windows SDK (for signtool.exe) and a valid code signing certificate
  • macOS notarization: Not implemented; requires Apple Developer account and xcrun notarytool

Known Gaps

Gap Impact Status
CHANGELOG.md missing CI release quality gate will fail ❌ Needs creation before first release
CONTRIBUTING.md missing CI release quality gate will fail ❌ Needs creation before first release
No git tags exist First release will be tagged v0.1.0
Updater disabled by default No in-app update notifications 🟡 Enable when Tauri signing keys are set
macOS notarization absent Gatekeeper warning on first launch 📝 Planned for v1 readiness
Version inconsistency (tauri.conf.json hardcodes 0.0.0) Overridden by CI patching; manual builds use wrong version 🟡 Acceptable
Browser extension in separate repo ADM release does not publish extension 🔄 Separate workflow
Release approval gating No manual approval step before publish 🟡 Can be added to CI if needed