diff --git a/.github/workflows/images-release.yml b/.github/workflows/images-release.yml index a3bc6f8..853437a 100644 --- a/.github/workflows/images-release.yml +++ b/.github/workflows/images-release.yml @@ -389,14 +389,24 @@ jobs: shell: bash run: | set -euo pipefail - checksum_file="$(mktemp)" - find release-assets -type f -print0 | sort -z | xargs -0 sha256sum > "$checksum_file" - mv "$checksum_file" release-assets/SHA256SUMS + mkdir release-upload + while IFS= read -r -d '' source; do + asset="$(basename "$source")" + [[ "$asset" != SHA256SUMS ]] || continue + [[ ! -e "release-upload/$asset" ]] || { echo "duplicate release asset: $asset" >&2; exit 1; } + cp "$source" "release-upload/$asset" + done < <(find release-assets -type f -print0 | sort -z) + ( + cd release-upload + checksum_file="$(mktemp)" + find . -maxdepth 1 -type f ! -name SHA256SUMS -printf '%f\0' | sort -z | xargs -0 -r sha256sum -- > "$checksum_file" + mv "$checksum_file" SHA256SUMS + ) - uses: actions/attest-build-provenance@v4 with: subject-path: | - release-assets/*.deb - release-assets/*.pkg.tar.zst + release-upload/*.deb + release-upload/*.pkg.tar.zst - name: Create or update this repository's package release env: GH_TOKEN: ${{ github.token }} @@ -407,7 +417,7 @@ jobs: if ! gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --target "$GITHUB_SHA" --title "mesh-llm ${{ needs.plan.outputs.mesh_version }} packages" --notes "Packages derived from verified Mesh-LLM/mesh-llm ${{ needs.plan.outputs.mesh_ref }} at ${{ needs.plan.outputs.mesh_sha }}." fi - find release-assets -type f -print0 | xargs -0 gh release upload "$TAG" --repo "$GITHUB_REPOSITORY" --clobber + find release-upload -maxdepth 1 -type f -print0 | xargs -0 gh release upload "$TAG" --repo "$GITHUB_REPOSITORY" --clobber readiness: name: Packaging readiness manifest diff --git a/README.md b/README.md index 2b1ff43..bacb6c1 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,19 @@ There is no source checkout or compilation path in this repository. `native-runt The exact rows live in `packaging/images.json`; `scripts/image-matrix.ts validate` enforces the archive/package relationship. +## Published artifacts + +- [Packaging releases](https://github.com/Mesh-LLM/mesh-packaging/releases/latest) + contain the versioned `.deb` and `.pkg.tar.zst` files, checksum sidecars, + aggregate `SHA256SUMS`, SPDX SBOMs, provenance records, and the Apple Silicon + Homebrew formula. +- [GHCR](https://github.com/orgs/Mesh-LLM/packages/container/package/mesh-llm) + contains public CPU, Vulkan, CUDA, and ROCm runtime images. See + [`docs/tagging.md`](docs/tagging.md) for immutable and moving tag names. + +Package-manager repositories and a public Homebrew tap are not published. The +native packages and formula are directly downloadable GitHub Release assets. + ## Automation `.github/workflows/images-release.yml` accepts the `mesh-llm-release` repository dispatch event and safe manual backfills. Every manual run defaults to `dry_run=true`. Dry-run mode forces both publish switches off while still downloading, checksumming, packaging, installing, image-building, and Homebrew-testing the selected rows. diff --git a/TODO.md b/TODO.md index b1fc766..70a2055 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,20 @@ # Production Readiness TODO +- [x] Replace former `Mesh-LLM/mesh-agent-images` repository references after + the repository rename. QA: `rg -n 'mesh-agent-images' --glob '!TODO.md' .` + returns no matches, `scripts/image-matrix.ts validate` passes, and all 12 + TypeScript tests pass locally. + +- [x] Publish a flat, self-consistent aggregate checksum manifest. QA: the + release staging simulation rejects basename collisions and its generated + `SHA256SUMS` passes `sha256sum -c`; the live `packaging-v0.73.1` manifest + exactly matches all 46 non-manifest GitHub asset digests, does not hash + itself, and workflow lint passes locally. + +- [x] Keep the rendered Homebrew formula acceptable to Homebrew's style and + install checks. QA: Homebrew release unit tests pass, `brew style` accepts the + rendered formula, and the formula installs and tests on Apple Silicon. + The current packaging and image pipeline is functional, but production readiness requires broader validation, supply-chain hardening, and a final publishing strategy. diff --git a/docker/Dockerfile.mesh-llm b/docker/Dockerfile.mesh-llm index 5cde48e..a73aa5a 100644 --- a/docker/Dockerfile.mesh-llm +++ b/docker/Dockerfile.mesh-llm @@ -40,7 +40,7 @@ ARG MESH_LLM_SOURCE_SHA ARG MESH_LLM_REPOSITORY=Mesh-LLM/mesh-llm LABEL org.opencontainers.image.title="mesh-llm" \ org.opencontainers.image.description="Packaged mesh-llm runtime" \ - org.opencontainers.image.source="https://github.com/Mesh-LLM/mesh-agent-images" \ + org.opencontainers.image.source="https://github.com/Mesh-LLM/mesh-packaging" \ org.opencontainers.image.licenses="MIT OR Apache-2.0" \ org.opencontainers.image.version="${MESH_LLM_VERSION}" \ org.opencontainers.image.revision="${MESH_LLM_SOURCE_SHA}" \ diff --git a/docs/packaging-readiness-gaps.md b/docs/packaging-readiness-gaps.md index 1269a86..4ebe960 100644 --- a/docs/packaging-readiness-gaps.md +++ b/docs/packaging-readiness-gaps.md @@ -10,16 +10,16 @@ The repository implementation is archive-first: it verifies already-built upstre - [x] Make dry-run execute all validation while forcibly skipping publication. QA: workflow policy and final readiness job. - [x] Remove Blacksmith/self-hosted orchestration. QA: precheck scans workflow/Docker paths for legacy runner/source-build strings. - [x] Correct channel claims: block Alpine/musl and Intel macOS; enable upstream Linux Vulkan and arm64 CUDA 13. QA: matrix tests. -- [x] Make GPU package and image QA accurate on GitHub-hosted runners. QA: CUDA package startup uses the vendor SDK driver stub, final CUDA images report only `libcuda.so.1` as host-injected, the lean ROCm 7.0 image stays within hosted disk, and full dry run [29455769787](https://github.com/Mesh-LLM/mesh-agent-images/actions/runs/29455769787) succeeds. +- [x] Make GPU package and image QA accurate on GitHub-hosted runners. QA: CUDA package startup uses the vendor SDK driver stub, final CUDA images report only `libcuda.so.1` as host-injected, the lean ROCm 7.0 image stays within hosted disk, and full dry run [29455769787](https://github.com/Mesh-LLM/mesh-packaging/actions/runs/29455769787) succeeds. ## Operational work outside this checkout - [ ] Provision an upstream fine-grained dispatch credential or GitHub App with Contents write access to this repository. QA: a published upstream release creates one receiver run without a personal broad-scope token. -- [x] Run and observe a full v0.73.1 dry run from this branch. QA: [run 29455769787](https://github.com/Mesh-LLM/mesh-agent-images/actions/runs/29455769787) completed all 35 jobs in 9m57s with the readiness manifest successful and both publish jobs skipped. -- [x] Exercise the production `repository_dispatch` ingress against merged `main` with publication disabled. QA: [run 29512465086](https://github.com/Mesh-LLM/mesh-agent-images/actions/runs/29512465086) completed all 35 jobs successfully in 11m07s; the readiness manifest succeeded and both publish jobs were skipped. +- [x] Run and observe a full v0.73.1 dry run from this branch. QA: [run 29455769787](https://github.com/Mesh-LLM/mesh-packaging/actions/runs/29455769787) completed all 35 jobs in 9m57s with the readiness manifest successful and both publish jobs skipped. +- [x] Exercise the production `repository_dispatch` ingress against merged `main` with publication disabled. QA: [run 29512465086](https://github.com/Mesh-LLM/mesh-packaging/actions/runs/29512465086) completed all 35 jobs successfully in 11m07s; the readiness manifest succeeded and both publish jobs were skipped. - [x] Restrict the `release` environment to deployments from `main`. QA: GitHub environment branch policy reports only `main`. - [ ] Add required reviewers to the `release` environment when the repository plan supports it. QA: a non-dry publish rehearsal pauses for approval before any write-capable job. - [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. -- [ ] Grant this repository's Actions identity write access to the existing `ghcr.io/mesh-llm/mesh-llm` package, which is currently linked to `Mesh-LLM/mesh-llm`. QA: the first controlled publish pushes a versioned matrix tag with `GITHUB_TOKEN` from this repository. -- [ ] Choose the GHCR package visibility before the first production publish. The existing package is private, and making it public is irreversible. QA: an unauthenticated pull succeeds if public distribution is selected. +- [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. diff --git a/docs/release-checklist.md b/docs/release-checklist.md index 47f69df..ba1628d 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -28,5 +28,5 @@ - [ ] Upstream has a fine-grained `MESH_AGENT_IMAGES_DISPATCH_TOKEN` or GitHub App installation with Contents write access scoped to this repository. - [ ] Upstream sends `mesh-llm-release` only after its complete non-canary release is published, with both publication switches enabled. - [ ] The first automated dispatch is observed end-to-end before enabling publication by dispatch payload. -- [ ] The existing `ghcr.io/mesh-llm/mesh-llm` package grants Actions write access to `Mesh-LLM/mesh-agent-images`. +- [ ] The existing `ghcr.io/mesh-llm/mesh-llm` package grants Actions write access to `Mesh-LLM/mesh-packaging`. - [ ] The GHCR package visibility is intentionally selected; public visibility cannot be reverted to private. diff --git a/packaging/homebrew/Formula/mesh-llm.rb.template b/packaging/homebrew/Formula/mesh-llm.rb.template index b18202c..9889b9d 100644 --- a/packaging/homebrew/Formula/mesh-llm.rb.template +++ b/packaging/homebrew/Formula/mesh-llm.rb.template @@ -1,14 +1,13 @@ class MeshLlm < Formula desc "Local mesh-llm CLI runtime" homepage "https://github.com/Mesh-LLM/mesh-llm" - license any_of: ["MIT", "Apache-2.0"] + 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"] depends_on arch: :arm64 - url "https://github.com/Mesh-LLM/mesh-llm/releases/download/v{{VERSION}}/{{ASSET}}" - sha256 "{{MACOS_ARM64_SHA256}}" - def install # Homebrew strips the archive's single mesh-bundle/ top-level directory. bin.install "mesh-llm"