Postguy
Contributing

Releasing

How a tagged release builds the macOS, Windows and Linux packages, which secrets sign them, and how to run each packaging script locally.

.github/workflows/release.yml builds releases. The canonical notes live in packaging/README.md, next to the scripts. This page summarises them.

Release flow

The workflow runs in two cases:

  • A tag matching v* is pushed. The tag names the version.
  • You start it by hand through workflow_dispatch, with an optional version override such as 0.2.0-rc.1.

Set the version

The version lives in exactly one place: [workspace.package] version in the root Cargo.toml.

cargo xtask version          # print it
cargo xtask version set X.Y.Z
  • The format is X.Y.Z or X.Y.Z-pre.release.
  • A version containing - marks the GitHub release as a pre-release.
  • In deb and rpm packages, a pre-release such as 0.2.0-rc.1 becomes 0.2.0~rc.1.

Push the tag only

git tag v1.2.3
git push origin v1.2.3

Do not create the GitHub release by hand. The workflow creates a draft. It refuses to update a release that is already published.

Wait for the jobs

  • version resolves and validates the version.
  • macos, windows (x64, x86, arm64) and linux (x86_64, aarch64) build in parallel.
  • flatpak builds from the Linux tarball, so it needs linux.
  • release then collects every artifact.

Publish the draft

The release job writes SHA256SUMS.txt over all artifacts. It creates the draft release v<version> titled Postguy v<version> with generated notes. Re-running for a tag whose release is still a draft replaces its assets. Review the draft and publish it by hand.

A manual run with a version override applies it with cargo xtask version set inside the job. Cargo.toml in the repository does not change.

Artifacts

Files appear in dist/release/.

PlatformScriptArtifacts
macOS universalpackaging/macos/package.sh --arch universalpostguy-<v>-macos-universal.dmg, postguy-<v>-macos-universal.zip (the app), postguy-cli-<v>-macos-universal.tar.gz. Developer ID codesign and notarization.
Windows x64, x86, arm64packaging/windows/package.ps1 -Arch <arch>postguy-<v>-windows-<arch>.msi (WiX v5), postguy-<v>-windows-<arch>.zip (portable), postguy-cli-<v>-windows-<arch>.zip. Azure Trusted Signing or a PFX.
Linux x86_64, aarch64packaging/linux/package.shpostguy-<v>-linux-<arch>.AppImage (plus .AppImage.zsync when zsyncmake is present), .deb, .rpm, .tar.gz, and postguy-cli-<v>-linux-<arch>.tar.gz.
Flatpakpackaging/linux/flatpak-bundle.shpostguy-<v>-linux-<arch>.flatpak

Not built: WebAssembly (there is no web build), riscv64, FreeBSD and Arch. FreeBSD users build from source.

Build hosts:

  • macOS: macos-15. The universal binary cross-compiles x86_64 on it.
  • Windows: windows-latest.
  • Linux: ubuntu-22.04 and ubuntu-22.04-arm, so packages need glibc 2.35 or newer.
  • Flatpak: ubuntu-24.04 and ubuntu-24.04-arm.

The Linux job uses the public storytold/craft-common-actions/actions/install-linux-deps action to install build libraries and nfpm. It is the one outside dependency.

Icons are derived at packaging time from assets/logo. No generated icon is committed.

Signing

Signing secrets are optional. Without them the scripts warn and ship unsigned (ad-hoc signed on macOS), so a release works with no secrets.

Set the secrets on the repository's release environment. It must exist (Settings, Environments) even when empty.

PlatformSecrets
macOSAPPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, KEYCHAIN_PASSWORD, APPLE_ID, APPLE_PASSWORD, APPLE_TEAM_ID
Windows (Azure Trusted Signing)AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_SIGNING_ENDPOINT, AZURE_SIGNING_ACCOUNT, AZURE_CERT_PROFILE
Windows (PFX alternative)WINDOWS_CERTIFICATE, WINDOWS_CERTIFICATE_PASSWORD

Notarization needs a real signing identity plus APPLE_ID, an app-specific APPLE_PASSWORD and APPLE_TEAM_ID. The macOS job also runs packaging/macos/verify.sh after packaging.

Do not describe a release as signed or notarized on the install pages unless the draft's artifacts were actually built with these secrets.

Running the scripts locally

packaging/env.sh is shared setup for the bash scripts.

  • It reads the version from the root Cargo.toml. Override it with POSTGUY_VERSION.
  • It exports DIST (default dist/release), the application id io.github.zuramai.postguy, and the build date and commit.
packaging/macos/package.sh --arch universal      # or aarch64, x86_64
packaging/macos/package.sh --arch aarch64 --skip-build
packaging/macos/verify.sh --arch universal       # add --require-notarized to demand tickets

Without MACOS_SIGN_IDENTITY the app is ad-hoc signed, and Gatekeeper rejects it on other Macs. The minimum system version is macOS 11.0.

Optional tools for the Linux script: desktop-file-validate, appstreamcli and zsyncmake.

Packaging scripts are not part of cargo xtask ci. To verify a package, install it on a clean machine and run postguy-cli tools. The CLI has no --version flag.

Copyright © 2026