diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f6a3ed2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,84 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +permissions: + contents: write + id-token: write + attestations: write + +concurrency: + group: vsphere-cli-bundle-release-${{ github.ref }} + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-24.04 + timeout-minutes: 45 + steps: + - name: Check out immutable tag + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Validate release identity + shell: bash + run: | + set -euo pipefail + test "$GITHUB_REF_TYPE" = tag + version="${GITHUB_REF_NAME#v}" + [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] + test "$(git rev-parse HEAD)" = "$(git rev-list -n 1 "$GITHUB_REF_NAME")" + test "$(sed -n 's/^GOVMOMI_VERSION=//p' sources.lock.env)" = "$version" + test -z "$(git status --porcelain)" + + - name: Install checksum-pinned Go toolchain + shell: bash + run: | + set -euo pipefail + archive="$RUNNER_TEMP/go1.27.0.linux-amd64.tar.gz" + curl --proto '=https' --tlsv1.2 --fail --silent --show-error --location \ + --output "$archive" https://go.dev/dl/go1.27.0.linux-amd64.tar.gz + printf '%s %s\n' \ + 675c26c449cbb18fc24b74650de1eabbae6e16f64326fd85a283fb3b58280685 \ + "$archive" | sha256sum -c - + tar -C "$RUNNER_TEMP" -xzf "$archive" + printf '%s\n' "$RUNNER_TEMP/go/bin" >> "$GITHUB_PATH" + + - name: Rebuild and verify exact bundle + shell: bash + run: | + set -euo pipefail + scripts/test + scripts/package dist + version="${GITHUB_REF_NAME#v}" + artifact="dist/vsphere-cli-bundle-${version}-linux-amd64.tar.xz" + test -s "$artifact" + (cd dist && sha256sum "${artifact##*/}" > SHA256SUMS) + + - name: Attest release asset + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 + with: + subject-checksums: dist/SHA256SUMS + + - name: Publish immutable GitHub release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + version="${GITHUB_REF_NAME#v}" + artifact="dist/vsphere-cli-bundle-${version}-linux-amd64.tar.xz" + gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --verify-tag \ + --title "vSphere CLI Bundle ${version}" \ + --notes 'Deterministic Go 1.27.0 build from the pinned govmomi source coordinate, with pure numeric artifact versioning and checksummed provenance.' \ + "$artifact" dist/SHA256SUMS + + - name: Clean generated files + if: always() + shell: bash + run: rm -rf -- dist diff --git a/ORIGIN.md b/ORIGIN.md index fa9c25d..6b491f0 100644 --- a/ORIGIN.md +++ b/ORIGIN.md @@ -12,6 +12,6 @@ The packaged `govc` executable is built from: - License: Apache-2.0 - License file: `LICENSE.txt` -The pinned commit is the upstream dependency-maintenance commit published after `v0.55.1` that updates `golang.org/x/text` to its security-fixed version. It is recorded as an exact source coordinate, not represented as a direct descendant of the reference tag. The package suffix makes this boundary explicit. The packaging recipe verifies the exact commit, dependency version, and SHA-256 of the upstream license before building. +The pinned commit is the upstream dependency-maintenance commit published after `v0.55.1` that updates `golang.org/x/text` to its security-fixed version. It is recorded as an exact source coordinate, not represented as a direct descendant of the reference tag. The suffix on the previous artifact remains immutable historical evidence; the current publication uses pure numeric version `0.55.2`. The packaging recipe verifies the exact commit, dependency version, and SHA-256 of the upstream license before building. The root MIT license applies only to PastureStack-authored packaging code and documentation. The upstream copyright and Apache-2.0 terms remain intact and are reproduced in every release archive. diff --git a/README.md b/README.md index 4eac5a5..bd1359b 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ This repository contains an independent, deterministic packaging recipe for the ## Release asset -The expected output is: +The current recipe produces: ```text -vsphere-cli-bundle-0.55.1-pasturestack.2-linux-amd64.tar.xz +vsphere-cli-bundle-0.55.2-linux-amd64.tar.xz ``` The archive contains: @@ -23,7 +23,7 @@ vsphere-cli-bundle-THIRD-PARTY-NOTICES.txt Run `scripts/test` in an Ubuntu environment with Git, GNU tar, xz, and Go 1.27.0. The test performs two independent builds, compares the archives byte for byte, verifies the fixed source and license, checks the executable format and build metadata, and exercises the compatibility command surface. -The current package pins the first upstream commit published after `v0.55.1` that updates `golang.org/x/text` to the security-fixed `v0.39.0`. The `pasturestack.2` suffix keeps that exact source boundary while recording the Go 1.27 rebuild that replaces the earlier Go 1.26.5 artifact; it is not represented as an unmodified upstream release or as a direct descendant of the reference tag. +The package pins the first upstream commit published after `v0.55.1` that updates `golang.org/x/text` to the security-fixed `v0.39.0`. The historical `pasturestack.2` suffix recorded that source boundary and the Go 1.27 rebuild that replaced the earlier Go 1.26.5 artifact. It remains only in immutable historical evidence. The current publication rebuilds and verifies the bundle as the pure numeric successor `v0.55.2`; product identity and provenance belong in package metadata, not the version string. ## Distribution model diff --git a/sources.lock.env b/sources.lock.env index 9938a69..1fe0805 100644 --- a/sources.lock.env +++ b/sources.lock.env @@ -1,4 +1,4 @@ -GOVMOMI_VERSION=0.55.1-pasturestack.2 +GOVMOMI_VERSION=0.55.2 GOVMOMI_REFERENCE_TAG=v0.55.1 GOVMOMI_COMMIT=a668d9c60399552ea96782b8751c956720a0b8fb GOVMOMI_SHORT_COMMIT=a668d9c60399 @@ -9,4 +9,4 @@ GOVMOMI_RELEASE_DATE=2026-07-07T14:02:15Z GOVMOMI_X_TEXT_VERSION=0.39.0 SOURCE_DATE_EPOCH=1783432935 BUILD_GO_VERSION=1.27.0 -GOVC_BINARY_SHA256=a42b0649c723b76a2208467c821ff1a9b713b2c8c5ab762808c1d193bd112287 +GOVC_BINARY_SHA256=f8c7d82a614655c83ee119e3f170a302a9b35d9ca7efd13bbc226df2d68e5d31