Releasing Imago
The release pipeline is .github/workflows/release.yml.
It runs on every push to the release branch. A maintainer
can also dispatch it manually, with an optional version override such as
1.2.0-rc.1; the release environment's branch restrictions
still apply.
Prepare and start a release
- Merge the release-ready changes into
release. - Set the workspace version in
Cargo.toml(for example, withcargo xtask version set 1.2.0). For a manual workflow run, the version input can override the workspace version for that run. Use a semantic version such as1.2.0or1.2.0-rc.1; versions containing a hyphen are marked as prereleases. - Push to
release, or dispatch the workflow onrelease(a dispatch on another branch is a dry run; see below). - Check the workflow run and its artifacts. On success, the workflow
creates or updates a draft GitHub Release named
Imago v<version>, targeted at the commit that triggered the run. Review the draft and itsSHA256SUMS.txt, then publish it in GitHub Releases when ready.
The workflow replaces assets when it updates an existing draft. It stops rather than overwriting a release that has already been published, so bump the version before producing another release.
Builds and artifacts
Release jobs build macOS universal, Windows x86/x64/ARM64, Linux
x86_64/aarch64/riscv64, FreeBSD x86_64, and the WASM web app. The
platform scripts in packaging/
write their outputs to dist/release/ (the full list of
files is the README's Downloads section):
- macOS: app DMG and CLI ZIP.
- Windows: MSI installer and portable ZIP for each architecture.
- Linux: AppImage (with its
.AppImage.zsync),.deb,.rpm, and.tar.gzfor each architecture (packaging/linux/package.sh). Each AppImage embedsgh-releases-zsync|storytold|imago|latest|imago-*-linux-<arch>.AppImage.zsync, so AppImageUpdate fetches only the changed blocks from the latest published (non-pre-) release. - Linux riscv64:
.tar.gzonly, cross-compiled on Ubuntu 24.04 against its riscv64 ports libraries (so glibc 2.39 or newer), with the CLI smoke-tested under QEMU (CROSS_*variables ofpackaging/linux/package.sh). - Flatpak: a single-file
.flatpakbundle for each architecture, repackaged from that architecture's Linux tarball (packaging/linux/flatpak-bundle.shwithpackaging/linux/flatpak/com.ncdev.imago.bundle.yml; no Rust build). The from-source manifestcom.ncdev.imago.ymlis for Flathub; packaging-lint keeps their runtime andfinish-argsidentical. - FreeBSD:
imago-<version>-freebsd-x86_64.tar.gz, a/usr/local-style tree built in a FreeBSD 14.3 VM (packaging/freebsd/package.sh, the same packages asfreebsd.yml). Install withtar -xzf <file> --strip-components 1 -C /usr/local. - Web:
imago-web-<version>.zip.
Only the macOS, Windows and draft-release jobs use the
release environment. The others sign nothing, so
dispatching the workflow on a branch
(gh workflow run release.yml --ref <branch>) dry-runs
them: the signing jobs are refused by the environment's branch rule, and
the release job, which needs them, is skipped.
The Linux builds run on Ubuntu 22.04 and target glibc 2.35 or newer.
AppImages and binaries may also require system libraries for the
windowing stack; the .deb and .rpm packages
declare their runtime dependencies.
Release builds fetch the pinned storytold/craft-fonts
revision and require it (CRAFT_FONTS_REQUIRED=1). Keep that
pin deliberate when updating the workflow, and bump it (in
release.yml, five jobs, and freebsd.yml)
whenever craft-fonts adds a face a shipped language needs: a stale pin
still builds, it just ships tofu (issue #319: v0.4.0 pinned a revision
from before Noto Sans CJK SC, so Simplified Chinese had no glyphs).
Before a release, check the pin against craft-fonts'
fonts/manifest.txt and run
CRAFT_FONTS_DIR=../craft-fonts cargo test -p imago-ui-egui i18n,
whose glyph-coverage test checks the characters in available faces.
CRAFT_FONTS_REQUIRED=1 now also makes the native build fail
if the pinned manifest lacks Noto Sans CJK SC Regular
(Hans) or BIZ UDPGothic Regular; the web build requires BIZ
UDPGothic Regular and packages Noto Sans CJK SC as a separate asset.
Local macOS, Linux and Windows packaging scripts automatically use
the sibling ../craft-fonts checkout. If it is absent, they
clone it at revision
3d9ab3a132ed0eff457e424226a435a901da30d3 (keep the pins in
packaging/fonts.sh and
packaging/windows/fonts.ps1 in sync with the release
workflow). Existing checkouts are left untouched. Set
CRAFT_FONTS_DIR to use another checkout; relative paths
resolve from the workspace root. The script requires the Chinese and
Japanese UI faces and includes their OFL licences in the package.
Download failures or incomplete checkouts stop packaging with an error.
--skip-build (-SkipBuild on Windows) packages
existing binaries without downloading fonts or changing what they embed;
pass the same CRAFT_FONTS_DIR used to compile them so their
licences ship.
Signing credentials
All credentials are stored as secrets in the GitHub
release environment. Signing is optional: without platform
signing credentials, packaging continues with unsigned artifacts and
warnings. macOS notarization is a separate optional step; when its
credentials are absent, a build with a signing identity is signed but
not notarized. Configure only the platform credentials you need:
- macOS signing:
APPLE_CERTIFICATE,APPLE_CERTIFICATE_PASSWORD, andKEYCHAIN_PASSWORD. Notarization additionally needs all ofAPPLE_ID,APPLE_PASSWORD(an app-specific password), andAPPLE_TEAM_ID. - Windows signing: either
WINDOWS_CERTIFICATEandWINDOWS_CERTIFICATE_PASSWORD, or Azure Trusted Signing credentials:AZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_SIGNING_ENDPOINT,AZURE_SIGNING_ACCOUNT, andAZURE_CERT_PROFILE.
Linux and web artifacts are not code-signed by this workflow. The release job computes SHA-256 checksums for the complete artifact set and attaches the checksum file to the draft release.