build: harden release provenance and package metadata - #1
Merged
Conversation
Every mcli published so far is stamped as built from a dirty tree, and several guards around the release were either unreachable or untested. Provenance: - Ignore dist/. GoReleaser writes there before building, so the Go toolchain saw an untracked path and marked every release binary +dirty / vcs.modified=true, breaking the link between an artifact and its tag. - Add buildscripts/verify-build-provenance.sh and run it from both the release and test workflows, so a stray untracked file fails the build rather than silently degrading provenance. - Assert a clean checkout before building a release. - Drop the root .goreleaser.yml. Nothing referenced it, and it had diverged into a config that would publish a non-draft release in replace mode and push pgsty/mc:latest if goreleaser were ever invoked without --config. - Replace `go mod tidy` in the release hooks with `go mod verify` so a release build can no longer rewrite go.mod, and gate tidiness on PRs. - Require find_binary to resolve exactly one binary per architecture instead of silently taking the first match. Package metadata: - Use the SPDX identifier AGPL-3.0-or-later, set Section: utils, and describe the client rather than the object store. - Keep /usr/local/bin/mcli. minio/pkger hardcodes that destination, so this matches every official MinIO package. Verification: - test-release.yml could not pass on ubuntu-latest: Debian's rpm2cpio exits non-zero even when it writes a correct payload, so the payload comparison tripped `set -o pipefail`. Use rpm -K and FILEDIGESTS. - Take the RPM metadata expectations from sign-release-rpms.sh so nfpm.yml and the signing script cannot drift apart and strand a release part-way through signing. - Build Dockerfile.goreleaser in CI. docker-release.yml is dispatch-only, so the image was otherwise never built until a real publish. - Assert architecture fields and apk metadata. CI: - Pin every action to a commit SHA and add dependabot to keep them fresh. - Add contents: read to go.yml and vulncheck.yml. - Remove issues.yaml, which fed miniohq's project board using a secret this fork does not have, and repoint the issue template away from MinIO's Slack. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pre-release hardening ahead of the 0804 authoritative release. No change to how packages are built or where they install; the packaging itself is left intact.
Provenance
Every
mclipublished so far is stamped+dirty/vcs.modified=true. GoReleaser writes intodist/before building,dist/was not ignored, so the Go toolchain saw an untracked path and marked every release binary as built from a modified tree — breaking the link between a published artifact and its tag.dist/.buildscripts/verify-build-provenance.sh, run from both the release and test workflows, asserting all six binaries carryvcs.revision == HEADandvcs.modified=false..goreleaser.yml. Nothing referenced it, and it had diverged into a config that would publish a non-draft release inreplacemode and pushpgsty/mc:latestifgoreleaserwere ever run without--config.go mod tidyin the release hooks withgo mod verify, and gate tidiness on PRs instead, so a release build can no longer rewritego.mod.find_binarymust resolve exactly one binary per architecture instead of silently taking the first match.Package metadata
AGPL-3.0-or-later(wasAGPLv3),Section: utils(was empty), and a description that describes the client rather than the object store./usr/local/bin/mcliis unchanged:minio/pkgerhardcodes that destination, so this matches every official MinIO package.Verification
test-release.ymlcould not pass onubuntu-latest. Debian'srpm2cpioexits non-zero even when it writes a correct payload, so the payload comparison trippedset -o pipefail:RHEL-family
rpm2cpioreturns 0, which is why it went unnoticed. This workflow last ran on 2026-03-12 against the pre-nFPM version; the current form has never executed. Replaced withrpm -KplusFILEDIGESTS.sign-release-rpms.sh, sonfpm.ymland the signing script cannot drift apart and strand a release part-way through signing.Dockerfile.goreleaseris built and smoke-tested in CI.docker-release.ymlis dispatch-only, so the image was otherwise never built until a real publish.CI
permissions: contents: readongo.ymlandvulncheck.yml.issues.yaml, which fedminiohq's project board using a secret this fork does not have; repointed the issue template away from MinIO's Slack.Local rehearsal
Full pipeline run in an isolated clone:
goreleaser check→ 6 binaries → provenance verified → 6 packages → all RPM/DEB/APK assertions → container build and run. The 93-line validation step was extracted verbatim from this YAML and executed on a Debian/Ubuntu toolchain (exit 0). Upgrade paths0801 → 0804and0803 → 0804verified for rpm, deb and apk.CI is the remaining proof layer — in particular the pinned action SHAs and the
rpm2cpiofix, both of which can only be confirmed on a real runner.🤖 Generated with Claude Code