diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 35d7831..473b3f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -103,13 +103,38 @@ jobs: # The tap repo (vhaudiquet/homebrew-ecrou) is a publish target, not # the source of truth: the formula is maintained in packaging/ and - # this job rewrites its url/sha256 for the release tarball and pushes - # it. Needs a PAT with push access to the tap repo as the + # this job rewrites its url/sha256 for the release tarball (the + # binary publish-release just attached) and pushes it. Needs a PAT with push access to the tap repo as the # HOMEBREW_TAP_TOKEN secret; without it the job is a no-op so tags # still release. - update-homebrew: + # The Homebrew formula pours this tarball, so it has to be attached + # to the release before the tap update runs. + publish-release: needs: build-macos runs-on: ubuntu-latest + permissions: + contents: write + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: ecrou-darwin-arm64 + path: dist + + - name: Create the release and upload the tarball + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + v="${GITHUB_REF_NAME#v}" + gh release create "v$v" --title "ecrou $v" --generate-notes || true + gh release upload "v$v" dist/* --clobber + + update-homebrew: + needs: publish-release + runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v4 @@ -130,7 +155,7 @@ jobs: fi v="${GITHUB_REF_NAME#v}" sha="$(cut -d' ' -f1 "dist/ecrou-v$v-darwin-arm64.tar.gz.sha256")" - url="https://github.com/vhaudiquet/ecrou/archive/refs/tags/v$v.tar.gz" + url="https://github.com/vhaudiquet/ecrou/releases/download/v$v/ecrou-v$v-darwin-arm64.tar.gz" mkdir -p formula/Formula sed -e '/^ # Placeholder pin:/d' -e "s|^ url \"https://github.com/vhaudiquet/ecrou.git\", tag: \"v[0-9][0-9.]*\"$| url \"$url\"\n sha256 \"$sha\"|" packaging/homebrew/Formula/ecrou.rb > formula/Formula/ecrou.rb grep -q "sha256 \"$sha\"" formula/Formula/ecrou.rb diff --git a/SPEC.md b/SPEC.md index 1c60714..0f4c22e 100644 --- a/SPEC.md +++ b/SPEC.md @@ -340,7 +340,10 @@ no boot). `packaging/homebrew/Formula/ecrou.rb` installs into a `vhaudiquet/homebrew-ecrou` tap — the repo name is what makes `brew install vhaudiquet/ecrou/ecrou` resolve without an explicit -`brew tap`. The tap repo is a publish target, not the source of +`brew tap`. The formula pours the darwin tarball the release +workflow signs and attaches to the GitHub release: no local compile, +and the entitlement signature survives, which a rebuild here would +strip. The tap repo is a publish target, not the source of truth: the release workflow rewrites the formula's url/sha256 for the release tarball and pushes it (gated on a `HOMEBREW_TAP_TOKEN` PAT; without the secret the job no-ops). The formula carries the runtime @@ -349,8 +352,9 @@ builds from source with cargo, and re-signs the binary with the entitlements plist from `packaging/homebrew/` — brew bottles are ad-hoc signed, so the signature is part of the formula's install, not of the artifact. The in-repo formula's tag pin is a placeholder: -the release workflow rewrites url and sha256 when it pushes the -formula to the tap. Homebrew's tap-trust gate refuses dependencies +the release workflow rewrites url and sha256 (of the release asset, +not the source archive — they are different files) when it pushes +the formula to the tap. Homebrew's tap-trust gate refuses dependencies from third-party taps until their tap is trusted, so the README leads with `brew trust --tap libkrun/krun` and CI trusts the tap before its install; removing that tax is another argument for diff --git a/packaging/homebrew/Formula/ecrou.rb b/packaging/homebrew/Formula/ecrou.rb index 93b1998..a6cff13 100644 --- a/packaging/homebrew/Formula/ecrou.rb +++ b/packaging/homebrew/Formula/ecrou.rb @@ -11,7 +11,6 @@ class Ecrou < Formula # libkrun's Hypervisor.framework backend is arm64-only upstream. depends_on arch: :arm64 - depends_on "rust" => :build depends_on "libkrun/homebrew-krun/libkrun" depends_on "e2fsprogs" # A libarchive-capable mke2fs populates ext4 images from tarballs in @@ -19,13 +18,11 @@ class Ecrou < Formula depends_on "libarchive" def install - system "cargo", "build", "--release" - bin.install "target/release/ecrou" - # Hypervisor.framework grants VM creation only to binaries signed - # with the hypervisor entitlement; on current macOS the signature - # is a hard requirement, the same one krunkit's formula carries. - system "codesign", "--force", "--sign", "-", - "--entitlements", "packaging/homebrew/ecrou.entitlements", bin/"ecrou" + # CI signed the binary with the hypervisor entitlement (a hard + # requirement on current macOS, the same one krunkit's formula + # signs for); a rebuild here would strip the signature, so the + # release tarball's binary is poured as-is. + bin.install "ecrou" end def caveats