Skip to content

ci(release): extend release pipeline to Linux + macOS (3-platform matrix) - #17

Open
Haaaiawd wants to merge 9 commits into
masterfrom
feat/release-matrix-linux-macos
Open

Haaaiawd wants to merge 9 commits into
masterfrom
feat/release-matrix-linux-macos

Conversation

@Haaaiawd

@Haaaiawd Haaaiawd commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • prepare-release job creates/updates the tag's GitHub Release up front, so parallel platform publish steps always take action-gh-release's update path — eliminates the 422 already_exists / duplicate-release race (Getting 422 "already_exists" error on 2.2.2 softprops/action-gh-release#616, #705).
  • build-linux on ubuntu-22.04 (deliberately not ubuntu-latest: keeps the glibc floor at 2.35 matching documented Ubuntu 22.04+/Debian 12+ support, and sidesteps linuxdeploy's known 24.04 failures — tauri#14796). Proven -dev dep set from ci.yml + patchelf/file/libfuse2, a pkg-config preflight gate that fails fast with a precise missing list, cargo check compile gate, tauri build --bundles deb,appimage (avoids rpm under targets:"all"), then artifact verification and append-upload to the shared Release.
  • build-macos as a fail-fast: false matrix producing *_aarch64.dmg (native on arm64 runner) and *_x64.dmg (cross via rustup target) — Intel Macs stay covered, arch failures are isolated, and each artifact is a vanilla tauri build rather than a universal2 lipo we can't verify locally. A preflight guard fails loudly if bundle.macOS.signingIdentity is ever set without provisioned certs; unsigned/unnotarized is by design and logged.
  • scripts/verify_release_artifacts.sh — per-format sanity gate used by the new jobs: MZ+PE sig (exe), OLE2 magic (msi), ar member names (deb), ELF+AI\x02 marker (AppImage), koly trailer (dmg), gzip magic (updater tarballs), each with a minimum-size floor an order of magnitude below real artifact sizes. --selftest fabricates fixtures and passes 13/13 locally.
  • scripts/check_build_capabilities.mjs — node port of the Windows job's pwsh post-build check on gen/schemas/capabilities.json, so linux/macos get the same proof that capabilities resolved into the binary.
  • Release body rewritten as a three-platform download matrix + per-platform install notes + honest unsigned/Wayland caveats; kept byte-identical in all publish steps so the final text is order-independent.
  • build-windows steps are byte-identical — verified by diff; only its body: text changed (required for the 3-platform release notes). No needs: added to it either.
  • Docs: docs/PLATFORMS.md gains a release-artifacts/pipeline section; README download table + per-platform quickstarts updated to real artifact names.

Test plan

  • Push v2.0.6 (or re-tag) → workflow run: prepare-release green, three platform jobs parallel-green
  • Release page shows one Release with 5-6 assets: *_x64-setup.exe, *_x64_en-US.msi, *_amd64.deb, *_amd64.AppImage, *_aarch64.dmg, *_x64.dmg
  • Download each asset and run scripts/verify_release_artifacts.sh <file> locally
  • If the release page shows a duplicate empty Release (known API race), delete it

Not verifiable locally (no cargo / no runners)

Actual tauri build output names (globs used everywhere; verify step asserts existence), linuxdeploy behavior on the 22.04 image, and macOS x86_64 cross-compile of bundled C deps (rusqlite/sqlite) — standard rustup-target cross, but first run may surface surprises; checklist in delivery covers per-platform failure points.

Generated with Devin

haa and others added 9 commits October 8, 2026 10:04
- verify_release_artifacts.sh: per-format sanity checks for every release
  artifact (PE/MZ+PE sig, OLE2 msi, ar members for deb, ELF+AI\x02 for
  AppImage, koly trailer for dmg, gzip magic) plus minimum-size floors an
  order of magnitude below real sizes; --selftest fabricates fixtures
  (13/13 pass locally).
- check_build_capabilities.mjs: node port of the Windows job's pwsh
  post-build check on gen/schemas/capabilities.json so the linux/macos
  jobs get the same "capabilities actually resolved into the build" proof.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- prepare-release: materializes the GitHub Release in a ~seconds job so
  parallel platform publish steps always take action-gh-release's update
  path — eliminates the 422 already_exists / duplicate-release race
  (softprops/action-gh-release#616, #705). Step is tag-gated so
  workflow_dispatch builds still work.
- build-linux on ubuntu-22.04 (NOT ubuntu-latest): oldest supported base
  keeps glibc floor at 2.35 matching the documented Ubuntu 22.04+/
  Debian 12+ requirement, and sidesteps linuxdeploy's known 24.04
  failures (FUSE2 renamed to libfuse2t64; bundled strip dies on
  .relr.dyn in glibc>=2.36, tauri-apps/tauri#14796).
- apt deps = ci.yml's proven -dev set + patchelf/file/libfuse2 for
  bundling; pkg-config preflight gate fails fast with a precise missing
  list instead of dying 20min into bundling.
- tauri build --bundles deb,appimage — "all" would also try rpm, which
  needs rpmbuild we don't install.
- Artifacts sanity-checked via verify_release_artifacts.sh --strict,
  then appended to the shared Release.
- Release body rewritten as a three-platform download matrix (kept
  byte-identical in every publish step → order-independent final text).
- build-windows steps untouched apart from the body text.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two vanilla per-arch tauri builds (matrix, fail-fast: false) instead of
universal2: each artifact is the standard build path, independently
verifiable, and one failing arch can't block the other. aarch64 builds
natively on the arm64 runner; x86_64 cross-compiles via rustup target
(Tauri docs approach). universal2 would merge both into one download but
adds lipo + dual-target risk we can't verify locally — noted as a
follow-up option.

- Unsigned/notarized-by-design: preflight fails loudly if
  bundle.macOS.signingIdentity is ever set without provisioned certs
  (ad-hoc '-' signing is fine), and logs the Gatekeeper expectation.
- Same gates as linux: cargo check --target, capability files check,
  resolved-capabilities proof, dmg koly-trailer + size verification.
- Publishes dmg/*.dmg (+ optional macos/*.app.tar.gz) to the shared
  Release.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- PLATFORMS.md: packaging rows updated to the real CI artifacts and a
  new "Release 打包产物与流水线" section documents the job graph,
  per-platform artifact names, pre-publish checks, install steps, and
  the honesty constraints (ubuntu-22.04 glibc floor, dual-arch dmg over
  universal2, unsigned everywhere).
- README: platform table lists real artifact globs; Linux quickstart
  covers apt-deb + FUSE2 note for AppImage; macOS quickstart explains
  the aarch64/x64 dmg choice and the Gatekeeper bypass; CI/CD paragraph
  describes the parallel three-platform release.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Records TASK-012 (3-platform release pipeline) and the four
consequential decisions in DECISIONS.md: ubuntu-22.04 pin over
ubuntu-latest, prepare-release to kill the gh-release create race,
single-arch dmg matrix over universal2, and explicit deb/appimage
bundle pinning.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…undle/

`tauri build --target X` namespaces cargo's output directory — explicit
--target (even matching the host) emits to target/<triple>/release/, not
target/release/. Glob, artifact upload, and publish files for the macOS
job now use target/${{ matrix.target }}/release/bundle/.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant