diff --git a/.github/workflows/images-release.yml b/.github/workflows/images-release.yml index 7fa18d1..90e1293 100644 --- a/.github/workflows/images-release.yml +++ b/.github/workflows/images-release.yml @@ -337,8 +337,8 @@ jobs: brew tap-new mesh-llm/packaging-validation tap_formula="$(brew --repository)/Library/Taps/mesh-llm/homebrew-packaging-validation/Formula/mesh-llm.rb" cp artifacts/homebrew/Formula/mesh-llm.rb "$tap_formula" + brew audit --strict --online mesh-llm/packaging-validation/mesh-llm brew install --formula mesh-llm/packaging-validation/mesh-llm - mesh-llm --version brew test mesh-llm/packaging-validation/mesh-llm - uses: actions/upload-artifact@v7 with: diff --git a/README.md b/README.md index f4985e1..95f41c7 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,9 @@ The exact rows live in `packaging/images.json`; `scripts/image-matrix.ts validat - [npm](https://www.npmjs.com/package/@mesh-llm/sdk) receives the install-tested cross-platform SDK tarball when npm publication is enabled. -Package-manager repositories and a public Homebrew tap are not published. The -native packages and formula are directly downloadable GitHub Release assets. +Native packages remain directly downloadable GitHub Release assets. The +rendered Homebrew formula is also published through the canonical +[`Mesh-LLM/tap`](https://github.com/Mesh-LLM/homebrew-tap) tap. ## Automation diff --git a/docs/packaging-readiness-gaps.md b/docs/packaging-readiness-gaps.md index 4ebe960..2bdb536 100644 --- a/docs/packaging-readiness-gaps.md +++ b/docs/packaging-readiness-gaps.md @@ -22,4 +22,9 @@ The repository implementation is archive-first: it verifies already-built upstre - [x] Make this repository the canonical GHCR producer and retire upstream tag publication. QA: `mesh-llm` keeps only manual non-publishing client-image validation and its successful full release dispatches this repository. - [x] Grant this repository's Actions identity write access to the existing `ghcr.io/mesh-llm/mesh-llm` package, which is linked to `Mesh-LLM/mesh-llm`. QA: production [run 29852728714](https://github.com/Mesh-LLM/mesh-packaging/actions/runs/29852728714) pushes the versioned matrix tags with `GITHUB_TOKEN` from `Mesh-LLM/mesh-packaging`. - [x] Select public visibility for the GHCR package. QA: anonymous manifest inspection succeeds for every published image variant from production [run 29852728714](https://github.com/Mesh-LLM/mesh-packaging/actions/runs/29852728714). -- [ ] Create package repositories or a Homebrew tap only after signing/trust ownership exists. QA: format-specific signing dry run and documented key rotation. +- [x] Create the canonical Homebrew tap with defined ownership and a + secretless polling update workflow. QA: `Mesh-LLM/homebrew-tap` strictly + audits, installs, and tests each package-release formula before committing it. +- [ ] Create native Linux package repositories only after signing/trust + ownership exists. QA: format-specific signing dry run and documented key + rotation. diff --git a/docs/packaging-readiness-scorecard.md b/docs/packaging-readiness-scorecard.md index 0c203d1..5eeabee 100644 --- a/docs/packaging-readiness-scorecard.md +++ b/docs/packaging-readiness-scorecard.md @@ -8,9 +8,12 @@ Readiness is evidence-based, not a static percentage. A release is ready only wh | Matrix coverage | Schema validation and explicit active/blocked rows | Review when upstream asset inventory changes | | Package correctness | Native metadata, checksum, install, version/runtime command smoke | Full dry-run evidence | | OCI correctness | Image installs the exact package and repeats command smoke | Full dry-run evidence | -| Homebrew | Direct upstream arm64 archive, digest, install and test | Full dry-run evidence | +| Homebrew | Direct upstream arm64 archive, strict audit, install, test, and canonical tap sync | Validate each release before tap update | | Efficiency | 8 verified archives fan out to 11 package rows; no source builds | Record duration and cache behavior | | Publish safety | Dry-run override, job-local write permissions, release environment | Configure/approve environment and observe first publish rehearsal | | Automation | Repository dispatch receiver | Provision upstream fine-grained dispatch credential/App | -Alpine and Intel macOS are correctly represented as unsupported, not partial successes. Native package repositories and a Homebrew tap remain deliberately blocked by signing and ownership work. +Alpine and Intel macOS are correctly represented as unsupported, not partial +successes. Native Linux package repositories remain deliberately blocked by +signing and ownership work; Homebrew uses the upstream archive digest and tap +history as its trust and rollback record. diff --git a/docs/publishing.md b/docs/publishing.md index 8e1ec25..2193062 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -11,7 +11,14 @@ The release workflow has four publication states: Non-npm publish jobs use the `release` GitHub environment, whose deployment policy accepts only `main`, while npm publishing uses the separate `npm` environment described below. Publish jobs have job-local write permissions, and all build and validation jobs are read-only. Add required reviewers when the repository plan supports environment reviewers. The upstream tag must already have a non-draft GitHub Release, the repository must be exactly `Mesh-LLM/mesh-llm`, the ref and version must match, and the tag is resolved to an immutable commit SHA for provenance labels. -GitHub Release assets, GHCR, and npm are the enabled public channels. Do not create apt, apk, pacman, or Homebrew tap publication until signing/trust-root ownership and rollback procedures exist. Homebrew currently publishes a formula that references the immutable upstream macOS archive and its upstream-verified SHA256; it does not repackage that binary. +GitHub Release assets, GHCR, npm, and the +[`Mesh-LLM/tap`](https://github.com/Mesh-LLM/homebrew-tap) Homebrew tap are the +enabled public channels. Do not create apt, apk, or pacman repositories until +signing/trust-root ownership and rollback procedures exist. Homebrew publishes +a formula that references the immutable upstream macOS archive and its +upstream-verified SHA256; it does not repackage that binary. The tap polls this +repository's latest non-prerelease packaging release, validates and installs +the attached `mesh-llm.rb`, and commits it only when it changes. npm publishing uses the `npm` environment and OIDC trusted publishing for `Mesh-LLM/mesh-packaging`, workflow `images-release.yml`. The published package diff --git a/packaging/homebrew/Formula/mesh-llm.rb.template b/packaging/homebrew/Formula/mesh-llm.rb.template index 9889b9d..0429d42 100644 --- a/packaging/homebrew/Formula/mesh-llm.rb.template +++ b/packaging/homebrew/Formula/mesh-llm.rb.template @@ -2,7 +2,6 @@ class MeshLlm < Formula desc "Local mesh-llm CLI runtime" homepage "https://github.com/Mesh-LLM/mesh-llm" url "https://github.com/Mesh-LLM/mesh-llm/releases/download/v{{VERSION}}/{{ASSET}}" - version "{{VERSION}}" sha256 "{{MACOS_ARM64_SHA256}}" license any_of: ["MIT", "Apache-2.0"] diff --git a/packaging/homebrew/README.md b/packaging/homebrew/README.md index b4523bf..5664406 100644 --- a/packaging/homebrew/README.md +++ b/packaging/homebrew/README.md @@ -9,7 +9,19 @@ mesh-llm-v-aarch64-apple-darwin.tar.gz -> brew install and brew test on macos-15 ``` -Homebrew strips the archive's single `mesh-bundle/` top-level directory before the formula installs `mesh-llm`; this repository does not rebuild or re-tar the binary. Intel is intentionally unsupported until upstream publishes an x86_64 macOS archive. A dedicated tap remains out of scope until its ownership and update workflow are defined; the rendered formula can be attached to this repository's package release. +Homebrew strips the archive's single `mesh-bundle/` top-level directory before +the formula installs `mesh-llm`; this repository does not rebuild or re-tar the +binary. Intel is intentionally unsupported until upstream publishes an x86_64 +macOS archive. + +The rendered formula is attached to this repository's package release. +[`Mesh-LLM/homebrew-tap`](https://github.com/Mesh-LLM/homebrew-tap) polls the +latest non-prerelease package release, validates and installs the formula, and +then mirrors it into the public tap. Install it with: + +```bash +brew install Mesh-LLM/tap/mesh-llm +``` Render locally with: