diff --git a/docs/releasing.md b/docs/releasing.md new file mode 100644 index 00000000..e8e26cbc --- /dev/null +++ b/docs/releasing.md @@ -0,0 +1,84 @@ +# Releasing EffectCraft + +Every push to the `release` branch runs [`.github/workflows/release.yml`](../.github/workflows/release.yml). +It builds signed installers for macOS, Windows, Linux and the web, then creates or updates a +**draft** GitHub Release named `EffectCraft v`. Nobody sees a draft until a maintainer +publishes it. + +User-facing names say **EffectCraft**. Files, binaries and ids stay lowercase +(`effectcraft---.`). + +## Cutting a release + +1. **Bump the version** on `main`. It lives in one place, `[workspace.package] version` in the + root `Cargo.toml`: + + ```sh + 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 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. The run still +needs the `release` environment, which only the `release` branch can use, so pick that branch in +the dialog. + +## What gets built + +| Platform | Artifacts | Built on | +|---|---|---| +| macOS 11+ (universal: Apple silicon and Intel) | `effectcraft--macos-universal.dmg`, `effectcraft-cli--macos-universal.zip` | `macos-15` | +| Windows 10+ x64 | `effectcraft--windows-x64.msi`, `effectcraft--windows-x64-portable.zip` | `windows-latest` | +| Windows 10+ x86 (32-bit) | `effectcraft--windows-x86.msi`, `effectcraft--windows-x86-portable.zip` | `windows-latest` | +| Windows 11 ARM64 | `effectcraft--windows-arm64.msi`, `effectcraft--windows-arm64-portable.zip` | cross-compiled on `windows-latest` | +| Linux x86_64 | `effectcraft--linux-x86_64.{AppImage,deb,rpm,tar.gz}` | `ubuntu-22.04` | +| Linux aarch64 | `effectcraft--linux-aarch64.{AppImage,deb,rpm,tar.gz}` | `ubuntu-22.04-arm` | +| Web | `effectcraft-web-.zip` (a static site; see [web.md](web.md)) | `ubuntu-latest` | + +The ARM64 MSI is installed and run on ARM64 hardware by +[`windows-arm64.yml`](../.github/workflows/windows-arm64.yml). + +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. + +## Signing + +Every job runs in the `release` environment, which only the `release` branch can use and which +holds the signing 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` |