Files
effectcraft/docs/releasing.md
T
Brandon ThomasandClaude Opus 5.5 f953cd2855 Release prep: 0.8.0 and a Linux riscv64 release build (#669)
* Release prep: bump to 0.8.0 and add a Linux riscv64 release build

- release.yml: new `linux-riscv64` job, ported from GridCraft. It cross-compiles on
  ubuntu-24.04 against riscv64 libraries from ports.ubuntu.com (the Linux job's X11/Wayland/GL
  -dev packages plus ALSA), ships effectcraft-<v>-linux-riscv64.tar.gz, and smoke-tests
  effectcraft-cli under qemu-riscv64. The draft-release job now needs it, so its tarball is
  uploaded and covered by SHA256SUMS.txt.
- packaging/linux/package.sh: cross-compiles when CROSS_ARCH/CROSS_TARGET/CROSS_COMPILE are set
  (cargo --target, the cross strip, the EMULATOR smoke test), as GridCraft's does.
- Version 0.7.0 -> 0.8.0 (cargo xtask version set), Cargo.lock refreshed.
- README and docs/releasing.md list the riscv64 tarball.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Fix FreeBSD CI: pointer_wrap test harness, wasm32 target, clippy as_chunks

- pointer_wrap tests: the harnesses dropped run_ui's FullOutput with the font atlas upload still
  in textures_delta, and epaint 0.36's drop check panics on that in debug builds. Every
  pointer_wrap test failed on every platform; FreeBSD is the only CI that runs them. Clear the
  delta, as the other UI tests do.
- freebsd.yml: install wasm32-unknown-unknown in the VM. Without it the host plug-in test's build
  of examples/plugins/posterize-bands failed (E0463, no std) and the test skipped silently; now
  it builds and runs.
- media/convert.rs: chunks_exact(2) -> as_chunks::<2>() (clippy chunks_exact_to_as_chunks,
  new in Rust 1.99); same pairs, same dropped remainder.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-10 21:08:18 -04:00

8.1 KiB
Raw Blame History

Releasing EffectCraft

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 EffectCraft v<version>. Nobody sees a draft until a maintainer publishes it.

User-facing names say EffectCraft. Files, binaries and ids stay lowercase (effectcraft-<version>-<platform>-<arch>.<ext>).

Cutting a release

  1. Bump the version on main. It lives in one place, [workspace.package] version in the root Cargo.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.lock
    

    Open a PR titled Release: EffectCraft v0.4.0 with that change (Cargo.toml and our crates in Cargo.lock only) and merge it.

  2. Check the gate. Run cargo xtask ci on main (it runs clippy and the tests in release mode, as CI does), and check that main's CI is green on every platform.

  3. Push main to release (a fast-forward): git push origin main:release. The release branch is protected; only maintainers can push to it. The workflow starts by itself.

  4. Wait for the draft. When every job is green (macOS notarization is the slow part), the Releases page has a draft EffectCraft v0.4.0, tagged v0.4.0 on the pushed commit, with every artifact and SHA256SUMS.txt. Its notes are generated from the merged PRs.

  5. Check it. Download an installer or two, check them against SHA256SUMS.txt, and run effectcraft --version / effectcraft-cli --version. Read the job summaries: a ::warning:: means a signing secret was missing and that artifact is unsigned.

  6. 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 the v0.4.0 tag. 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) effectcraft-<v>-macos-universal.dmg, effectcraft-cli-<v>-macos-universal.zip macos-15
Windows 10+ x64 effectcraft-<v>-windows-x64.msi, effectcraft-<v>-windows-x64-portable.zip windows-latest
Windows 10+ x86 (32-bit) effectcraft-<v>-windows-x86.msi, effectcraft-<v>-windows-x86-portable.zip windows-latest
Windows 11 ARM64 effectcraft-<v>-windows-arm64.msi, effectcraft-<v>-windows-arm64-portable.zip cross-compiled on windows-latest
Linux x86_64 effectcraft-<v>-linux-x86_64.{AppImage,deb,rpm,tar.gz} ubuntu-22.04
Linux aarch64 effectcraft-<v>-linux-aarch64.{AppImage,deb,rpm,tar.gz} ubuntu-22.04-arm
Linux riscv64 effectcraft-<v>-linux-riscv64.tar.gz cross-compiled on ubuntu-24.04 (CLI smoke-tested under QEMU)
Linux AppImage updates effectcraft-<v>-linux-{x86_64,aarch64}.AppImage.zsync with the AppImages
Flatpak x86_64, aarch64 effectcraft-<v>-linux-{x86_64,aarch64}.flatpak (the Linux tarball, repackaged) ubuntu-24.04, ubuntu-24.04-arm
FreeBSD 14+ x86_64 effectcraft-<v>-freebsd-x86_64.tar.gz a FreeBSD 14.3 VM on ubuntu-latest
Web effectcraft-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.

Every binary reports its version: effectcraft --version, effectcraft-cli --version and Help › About EffectCraft.

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 effectcraft-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|effectcraft|latest|effectcraft-*-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/ai.storyteller.effectcraft.bundle.yml (no Rust build inside flatpak-builder), then install the bundle and run effectcraft-cli --version in the sandbox. ai.storyteller.effectcraft.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 effectcraft-<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