Releasing
.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 as0.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.ZorX.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.1becomes0.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
versionresolves and validates the version.macos,windows(x64, x86, arm64) andlinux(x86_64, aarch64) build in parallel.flatpakbuilds from the Linux tarball, so it needslinux.releasethen 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/.
| Platform | Script | Artifacts |
|---|---|---|
| macOS universal | packaging/macos/package.sh --arch universal | postguy-<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, arm64 | packaging/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, aarch64 | packaging/linux/package.sh | postguy-<v>-linux-<arch>.AppImage (plus .AppImage.zsync when zsyncmake is present), .deb, .rpm, .tar.gz, and postguy-cli-<v>-linux-<arch>.tar.gz. |
| Flatpak | packaging/linux/flatpak-bundle.sh | postguy-<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.04andubuntu-22.04-arm, so packages need glibc 2.35 or newer. - Flatpak:
ubuntu-24.04andubuntu-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.
| Platform | Secrets |
|---|---|
| macOS | APPLE_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.
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 withPOSTGUY_VERSION. - It exports
DIST(defaultdist/release), the application idio.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.
You need the Rust MSVC toolchain and target, and WiX v5. You need the Windows SDK (signtool.exe) only for signing.
dotnet tool install --global wix --version 5.0.2
wix extension add -g WixToolset.UI.wixext/5.0.2
wix extension add -g WixToolset.Util.wixext/5.0.2
pwsh packaging/windows/package.ps1 -Arch x64 # or x86, arm64
pwsh packaging/windows/package.ps1 -Arch x86 -SkipBuild
pwsh packaging/windows/test-msi.ps1 dist/release/postguy-0.1.0-windows-x64.msi
test-msi.ps1 needs an elevated shell. It installs the MSI silently into a temporary folder, checks the result, runs the CLI and uninstalls. package.ps1 runs it for x64 and x86 builds.
The arm64 build is cross-compiled and needs the MSVC ARM64 build tools. Binaries link the C runtime statically, so no Visual C++ redistributable is required.
You need cargo, curl, nfpm for deb and rpm, and appimagetool for the AppImage. If appimagetool is missing, the script downloads a pinned release and checks it against its SHA-256. Override with APPIMAGETOOL=/path.
Build on an old distribution, as CI does with Ubuntu 22.04, so the binaries run on newer ones.
packaging/linux/package.sh
packaging/linux/package.sh --skip-build --formats "deb rpm" # formats: appimage deb rpm tar cli
You need flatpak, flatpak-builder and librsvg2-common.
The bundle is built for the host architecture from a Linux tarball, which package.sh --formats tar creates first. The freedesktop runtime and SDK named in the manifest are installed per user from Flathub.
packaging/linux/package.sh --formats tar
packaging/linux/flatpak-bundle.sh # uses dist/release/postguy-<v>-linux-<arch>.tar.gz
packaging/linux/flatpak-bundle.sh --no-test path/to/postguy-<v>-linux-<arch>.tar.gz
Unless you pass --no-test, the script installs the bundle per user and lists the sandbox's files as a smoke test.
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.