Releasing Anima
Every push to the release branch runs .github/workflows/release.yml.
It builds signed installers for macOS and Windows, packages for Linux
and FreeBSD, and the web build, then creates or updates a
draft GitHub Release named
Anima v<version>. Nobody sees a draft until a
maintainer publishes it.
User-facing names say Anima. Files, binaries and ids
stay lowercase
(anima-<version>-<platform>-<arch>.<ext>).
Cutting a release
Bump the version on
main. It lives in one place,[workspace.package] versionin the rootCargo.toml:cargo xtask version # prints the current version, e.g. 0.3.1 cargo xtask version set 0.4.0 # or 0.4.0-rc.1; updates Cargo.toml and Cargo.lockOpen a PR titled
Release: Anima v0.4.0with that change (Cargo.tomland our crates inCargo.lockonly) and merge it.Check the gate. Run
cargo xtask cionmain(it runs clippy and the tests in release mode, as CI does), and check thatmain's CI is green on every platform.Push
maintorelease(a fast-forward):git push origin main:release. Thereleasebranch is protected; only maintainers can push to it. The workflow starts by itself.Wait for the draft. When every job is green (macOS notarization is the slow part), the Releases page has a draft
Anima v0.4.0, taggedv0.4.0on the pushed commit, with every artifact andSHA256SUMS.txt. Its notes are generated from the merged PRs.Check it. Download an installer or two, check them against
SHA256SUMS.txt, and runanima --version/anima-cli --version. Read the job summaries: a::warning::means a signing secret was missing and that artifact is unsigned.Publish the draft in the GitHub UI (or
gh release edit v0.4.0 --draft=false --latest), with a short Highlights section above the generated notes. Publishing creates thev0.4.0tag. Versions with a pre-release suffix (-rc.1) are marked as pre-releases.
Pushing to release again before you publish rebuilds the
same draft and replaces its assets. Once the draft is published, the
workflow refuses to touch that version again
(Release v<version> is already published. Bump the version (cargo xtask version set) before pushing to release.),
so bump it first.
Test runs: Actions › Release › Run workflow
runs the whole pipeline by hand. The optional version input
(such as 0.4.0-rc.1) overrides Cargo.toml for
that run only: the jobs apply it with
cargo xtask version set before building, so the binaries
report it too. Signing and the draft release need the
release environment, which only the release
branch can use. Run on any other branch
(gh workflow run release.yml --ref <branch>), it is a
dry run: the jobs that sign nothing (Linux, Flatpak, FreeBSD, web) build
and check everything, the macOS and Windows jobs are refused by the
environment's branch rule, and no draft release is made.
What gets built
| Platform | Artifacts | Built on |
|---|---|---|
| macOS 11+ (universal: Apple silicon and Intel) | anima-<v>-macos-universal.dmg,
anima-cli-<v>-macos-universal.zip |
macos-15 |
| Windows 10+ x64 | anima-<v>-windows-x64.msi,
anima-<v>-windows-x64-portable.zip |
windows-latest |
| Windows 10+ x86 (32-bit) | anima-<v>-windows-x86.msi,
anima-<v>-windows-x86-portable.zip |
windows-latest |
| Windows 11 ARM64 | anima-<v>-windows-arm64.msi,
anima-<v>-windows-arm64-portable.zip |
cross-compiled on windows-latest |
| Linux x86_64 | anima-<v>-linux-x86_64.{AppImage,deb,rpm,tar.gz} |
ubuntu-22.04 |
| Linux aarch64 | anima-<v>-linux-aarch64.{AppImage,deb,rpm,tar.gz} |
ubuntu-22.04-arm |
| Linux riscv64 | anima-<v>-linux-riscv64.tar.gz |
cross-compiled on ubuntu-24.04 (CLI smoke-tested under
QEMU) |
| Linux AppImage updates | anima-<v>-linux-{x86_64,aarch64}.AppImage.zsync |
with the AppImages |
| Flatpak x86_64, aarch64 | anima-<v>-linux-{x86_64,aarch64}.flatpak (the
Linux tarball, repackaged) |
ubuntu-24.04, ubuntu-24.04-arm |
| FreeBSD 14+ x86_64 | anima-<v>-freebsd-x86_64.tar.gz |
a FreeBSD 14.3 VM on ubuntu-latest |
| Web | anima-web-<v>.zip (a static site; see web.md) |
ubuntu-latest |
The ARM64 MSI is installed and run on ARM64 hardware by windows-arm64.yml.
The MSI's setup wizard (installer-ui.wxs)
lets people choose the install folder; upgrades and repairs reuse it,
and INSTALLFOLDER="..." picks it for a silent
(/qn) install. packaging-lint.yml
install-tests that with stub binaries (test-msi.ps1):
a custom folder, an upgrade that keeps it, a repair, uninstall, and the
Program Files default. The wizard pages themselves are checked by
hand.
The portable zip ships portable.txt
beside anima.exe. That marker (or an
Anima.portable file) switches on portable mode: the
settings folder (preferences, shortcuts, recovery files, logs, plug-ins)
becomes AnimaData\ next to the exe instead of
%APPDATA%\Anima. If that folder isn't writable the app logs
a warning and uses %APPDATA%. The MSI has no marker. The
logic is in crates/host/src/app_dirs.rs and works the same
on macOS and Linux; ANIMA_CONFIG_DIR still wins over
it.
Every binary reports its version: anima --version,
anima-cli --version and Help › About Anima.
Linux: the glibc baseline
Linux binaries link against the glibc of the machine that builds them
and need at least that version wherever they run. The release builds on
the oldest GitHub-hosted image, Ubuntu 22.04 (glibc
2.35), so the packages run on Ubuntu 22.04+, Debian 12+, Fedora
36+ and RHEL 10. Building on a newer image would silently raise that
floor. packaging/linux/package.sh builds the AppImage,
.deb, .rpm and tarball; the workflow then runs
the AppImage's --version as a smoke test.
Linux: riscv64
GitHub has no RISC-V runners, so the linux-riscv64 job
cross-compiles on ubuntu-24.04 for
riscv64gc-unknown-linux-gnu, against riscv64 libraries
(X11/Wayland/GL, ALSA) from ports.ubuntu.com. It ships the tarball only,
needs glibc 2.39 (Ubuntu 24.04+, Debian 13+), and runs
anima-cli --version under qemu-riscv64 as a
smoke test. package.sh cross-compiles when
CROSS_ARCH, CROSS_TARGET and
CROSS_COMPILE are set (see its header).
Linux: AppImage updates and Flatpak
Each AppImage embeds update information
(gh-releases-zsync|storytold|anima|latest|anima-*-linux-<arch>.AppImage.zsync),
and the .zsync file published beside it lets AppImageUpdate
and AppImageLauncher fetch only the changed blocks from the newest
published (non-pre-release) version. package.sh writes the
.zsync when zsyncmake (the zsync
package) is installed; the workflow checks both.
The .flatpak bundles repackage the Linux job's tarball
with packaging/linux/flatpak-bundle.sh and
packaging/linux/flatpak/com.ncdev.anima.bundle.yml (no Rust
build inside flatpak-builder), then install the bundle and run
anima-cli --version in the sandbox.
com.ncdev.anima.yml is the from-source manifest for
Flathub; packaging lint keeps the runtime and sandbox permissions of the
two identical.
FreeBSD
GitHub has no FreeBSD runners, so the job builds in a FreeBSD 14.3 VM
(vmactions/freebsd-vm, pinned by commit) with the packages
freebsd.yml
uses, and packaging/freebsd/package.sh makes a
/usr/local-style tarball:
tar -xzf anima-<v>-freebsd-x86_64.tar.gz --strip-components 1 -C /usr/local.
Signing
The macOS and Windows jobs and the draft-release job run in the
release environment, which only the release
branch can use and which holds the signing secrets. The jobs that sign
nothing run without it and get no secrets. Every secret is optional: a
missing one produces an unsigned artifact and a warning in the job
summary, never a failed build.
| Platform | Secrets |
|---|---|
| macOS (Developer ID signing and notarization) | APPLE_CERTIFICATE,
APPLE_CERTIFICATE_PASSWORD, KEYCHAIN_PASSWORD,
APPLE_ID, APPLE_PASSWORD,
APPLE_TEAM_ID |
| Windows (a certificate, or Azure Trusted Signing) | WINDOWS_CERTIFICATE,
WINDOWS_CERTIFICATE_PASSWORD, or
AZURE_TENANT_ID, AZURE_CLIENT_ID,
AZURE_CLIENT_SECRET, AZURE_SIGNING_ENDPOINT,
AZURE_SIGNING_ACCOUNT, AZURE_CERT_PROFILE |