diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..cb1e00a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,132 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +permissions: + contents: write + packages: write + id-token: write + attestations: write + +concurrency: + group: kubernetes-package-release-${{ github.ref }} + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-24.04 + timeout-minutes: 150 + env: + TARGET_REPOSITORY: ghcr.io/pasturestack/kubernetes-package + TRIVY_VERSION: 0.74.0 + TRIVY_ARCHIVE_SHA256: 2ae6fe3ee734b7fdf11335663e18c75ea12dccc76062f09f164a3b0f8be4371a + 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 + [[ "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] + test "$(git cat-file -t "refs/tags/$GITHUB_REF_NAME")" = tag + test "$(git rev-list -n 1 "$GITHUB_REF_NAME")" = "$GITHUB_SHA" + test -z "$(git status --porcelain)" + + - name: Install checksum-pinned Trivy + shell: bash + run: | + set -euo pipefail + archive="$RUNNER_TEMP/trivy.tar.gz" + curl --proto '=https' --tlsv1.2 --fail --silent --show-error --location \ + --output "$archive" \ + "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" + printf '%s %s\n' "$TRIVY_ARCHIVE_SHA256" "$archive" | sha256sum -c - + tar -xzf "$archive" -C "$RUNNER_TEMP" trivy + sudo install -m 0555 "$RUNNER_TEMP/trivy" /usr/local/bin/trivy + trivy image --download-db-only + + - name: Build, smoke-test, scan, and inventory exact tag + shell: bash + run: | + set -euo pipefail + scripts/release + test "$(cat dist/images)" = "pasturestack/kubernetes-package:$GITHUB_REF_NAME" + test -s dist/kubernetes-package.cdx.json + test -s dist/kubernetes-package.trivy.json + test -s dist/kubernetes-package.trivy-raw.json + version="${GITHUB_REF_NAME#v}" + tar --sort=name --owner=0 --group=0 --numeric-owner \ + -C dist -cJf "dist/kubernetes-package-${version}-evidence.tar.xz" \ + CNI-LOOPBACK-BUILDINFO.txt image-id.txt images \ + kubernetes-buildinfo kubernetes-package.cdx.json \ + kubernetes-package.image-inspect.json kubernetes-package.trivy-raw.json \ + kubernetes-package.trivy.json openvex.json rootfs-files.txt \ + source-revision.txt trivy-version.txt + sha256sum "dist/kubernetes-package-${version}-evidence.tar.xz" \ + dist/kubernetes-package.cdx.json dist/kubernetes-package.trivy.json \ + dist/openvex.json | LC_ALL=C sort -k2 > dist/RELEASE-SHA256SUMS + + - name: Publish immutable runtime image + id: publish + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + source_image="pasturestack/kubernetes-package:$GITHUB_REF_NAME" + target_image="$TARGET_REPOSITORY:$GITHUB_REF_NAME" + printf '%s' "$GH_TOKEN" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdin + docker tag "$source_image" "$target_image" + docker push "$target_image" + reference="$(docker image inspect --format '{{index .RepoDigests 0}}' "$target_image")" + digest="${reference#*@}" + [[ "$digest" =~ ^sha256:[0-9a-f]{64}$ ]] + printf 'digest=%s\n' "$digest" >> "$GITHUB_OUTPUT" + + - name: Attest release evidence + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 + with: + subject-checksums: dist/RELEASE-SHA256SUMS + + - name: Attest runtime image + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 + with: + subject-name: ${{ env.TARGET_REPOSITORY }} + subject-digest: ${{ steps.publish.outputs.digest }} + push-to-registry: true + + - name: Publish GitHub release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + version="${GITHUB_REF_NAME#v}" + gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --verify-tag \ + --title "Kubernetes Package $GITHUB_REF_NAME" \ + --notes 'Source-built Kubernetes component bundle published under its pure numeric upstream version, with smoke tests, vulnerability evidence, SBOM, checksums, and provenance.' \ + "dist/kubernetes-package-${version}-evidence.tar.xz" \ + dist/kubernetes-package.cdx.json \ + dist/kubernetes-package.trivy.json \ + dist/openvex.json \ + dist/RELEASE-SHA256SUMS + + - name: Clean run-owned resources + if: always() + shell: bash + run: | + set +e + docker logout ghcr.io >/dev/null 2>&1 + docker image rm -f \ + "pasturestack/kubernetes-package:$GITHUB_REF_NAME" \ + "$TARGET_REPOSITORY:$GITHUB_REF_NAME" >/dev/null 2>&1 + docker builder prune --all --force >/dev/null 2>&1 + rm -rf -- dist diff --git a/ORIGIN.md b/ORIGIN.md index f236d58..8406e0d 100644 --- a/ORIGIN.md +++ b/ORIGIN.md @@ -18,7 +18,7 @@ PastureStack claims only its later modifications and does not imply affiliation - Commit: `bb826b1d48562f110659e64e8ec444327433db95` - Source archive SHA-256: `3c28f11492472df48e658551bf268fd92938b127b0f9dcef7090ac800318c821` - License SHA-256: `cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30` -- Build-time dependency overrides: OpenTelemetry `v1.45.0`, OpenTelemetry gRPC instrumentation `v0.70.0`, gRPC-Go `v1.83.1`, `cel.dev/cel-go` `v0.32.0`, etcd `v3.7.1`, `go.etcd.io/raft/v3` `v3.7.0`, `x/crypto` `v0.55.0`, and `x/sys` `v0.47.0` +- Build-time dependency overrides: OpenTelemetry `v1.45.0`, OpenTelemetry gRPC instrumentation `v0.70.0`, gRPC-Go `v1.83.2`, `cel.dev/cel-go` `v0.32.0`, etcd `v3.7.1`, `go.etcd.io/raft/v3` `v3.7.0`, `x/crypto` `v0.56.0`, and `x/sys` `v0.47.0` ### CNI plug-ins diff --git a/README.md b/README.md index 0d8c6a9..0bf4e56 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,19 @@ This repository builds a compact, auditable bundle of current upstream Kubernete PastureStack is an independent community project and is not affiliated with or endorsed by Rancher Labs or SUSE. The preserved upstream history and Apache-2.0 attribution remain intact. +The previous public Release, `v1.12.10-pasturestack.4`, is immutable historical +evidence for the retired compatibility package. The maintained component +bundle uses pure numeric coordinate `v1.36.4`; product identity and provenance +are carried by the package name, labels, SBOM, and attestations rather than a +text qualifier in the tag. This component image is still not an in-place +upgrade path for a legacy Rancher 1.6 cluster. + ## Current payload - Kubernetes `v1.36.4`, exact upstream commit `bb826b1d48562f110659e64e8ec444327433db95`. - `kubeadm`, `kubelet`, `kube-proxy`, `kube-apiserver`, `kube-controller-manager`, `kube-scheduler`, and `kubectl` built from that source with Go `1.27.0`. - CNI plug-ins `v1.9.1` loopback binary built from the vendored upstream source with Go `1.27.0`. -- Current dependency overrides: OpenTelemetry `v1.45.0`, OpenTelemetry gRPC instrumentation `v0.70.0`, gRPC-Go `v1.83.1`, `cel.dev/cel-go` `v0.32.0`, etcd `v3.7.1`, `go.etcd.io/raft/v3` `v3.7.0`, `x/crypto` `v0.55.0`, and `x/sys` `v0.47.0`. +- Current dependency overrides: OpenTelemetry `v1.45.0`, OpenTelemetry gRPC instrumentation `v0.70.0`, gRPC-Go `v1.83.2`, `cel.dev/cel-go` `v0.32.0`, etcd `v3.7.1`, `go.etcd.io/raft/v3` `v3.7.0`, `x/crypto` `v0.56.0`, and `x/sys` `v0.47.0`. - Statically linked component binaries in a `scratch` runtime with only the required CA bundle, licenses, and build evidence. The image deliberately contains no Docker CLI, Azure CLI, Helm, Tiller, embedded cloud provider, legacy DNS add-on, dashboard, monitoring add-on, or Rancher metadata bootstrap logic. @@ -19,8 +26,8 @@ The image deliberately contains no Docker CLI, Azure CLI, Helm, Tiller, embedded The image contains no shell or wrapper process. Its `PATH` exposes only the packaged component binaries: ```sh -docker run --rm pasturestack/kubernetes-package:v1.36.4 kubectl version --client=true --output=json -docker run --rm pasturestack/kubernetes-package:v1.36.4 kubeadm version -o short +docker run --rm local/pasturestack/kubernetes-package:v1.36.4 kubectl version --client=true --output=json +docker run --rm local/pasturestack/kubernetes-package:v1.36.4 kubeadm version -o short ``` Node and control-plane components normally require host networking, persistent state, device or cgroup access, certificates, a CRI endpoint, and root privileges. Those privileges are deployment decisions and are never added automatically by this image. diff --git a/package/Dockerfile b/package/Dockerfile index 23a6b64..9b30d80 100644 --- a/package/Dockerfile +++ b/package/Dockerfile @@ -6,11 +6,11 @@ ARG KUBERNETES_SOURCE_SHA256=3c28f11492472df48e658551bf268fd92938b127b0f9dcef709 ARG KUBERNETES_LICENSE_SHA256=cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 ARG OPENTELEMETRY_VERSION=v1.45.0 ARG OPENTELEMETRY_GRPC_VERSION=v0.70.0 -ARG GRPC_GO_VERSION=v1.83.1 +ARG GRPC_GO_VERSION=v1.83.2 ARG CEL_GO_VERSION=v0.32.0 ARG ETCD_VERSION=v3.7.1 ARG ETCD_RAFT_VERSION=v3.7.0 -ARG X_CRYPTO_VERSION=v0.55.0 +ARG X_CRYPTO_VERSION=v0.56.0 ARG X_SYS_VERSION=v0.47.0 ENV GOMAXPROCS=2 GOTELEMETRY=off GOTOOLCHAIN=local @@ -129,11 +129,11 @@ ARG KUBERNETES_GIT_COMMIT=bb826b1d48562f110659e64e8ec444327433db95 ARG KUBERNETES_SOURCE_SHA256=3c28f11492472df48e658551bf268fd92938b127b0f9dcef7090ac800318c821 ARG OPENTELEMETRY_VERSION=v1.45.0 ARG OPENTELEMETRY_GRPC_VERSION=v0.70.0 -ARG GRPC_GO_VERSION=v1.83.1 +ARG GRPC_GO_VERSION=v1.83.2 ARG CEL_GO_VERSION=v0.32.0 ARG ETCD_VERSION=v3.7.1 ARG ETCD_RAFT_VERSION=v3.7.0 -ARG X_CRYPTO_VERSION=v0.55.0 +ARG X_CRYPTO_VERSION=v0.56.0 ARG X_SYS_VERSION=v0.47.0 ARG CNI_VERSION=v1.9.1 ARG CNI_GIT_COMMIT=adc3e6b5b581638afbd194cf2e9319ecbb0151a1 diff --git a/scripts/package b/scripts/package index 619ab26..6958938 100755 --- a/scripts/package +++ b/scripts/package @@ -15,11 +15,11 @@ KUBERNETES_SOURCE_SHA256=${KUBERNETES_SOURCE_SHA256:-3c28f11492472df48e658551bf2 KUBERNETES_LICENSE_SHA256=${KUBERNETES_LICENSE_SHA256:-cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30} OPENTELEMETRY_VERSION=${OPENTELEMETRY_VERSION:-v1.45.0} OPENTELEMETRY_GRPC_VERSION=${OPENTELEMETRY_GRPC_VERSION:-v0.70.0} -GRPC_GO_VERSION=${GRPC_GO_VERSION:-v1.83.1} +GRPC_GO_VERSION=${GRPC_GO_VERSION:-v1.83.2} CEL_GO_VERSION=${CEL_GO_VERSION:-v0.32.0} ETCD_VERSION=${ETCD_VERSION:-v3.7.1} ETCD_RAFT_VERSION=${ETCD_RAFT_VERSION:-v3.7.0} -X_CRYPTO_VERSION=${X_CRYPTO_VERSION:-v0.55.0} +X_CRYPTO_VERSION=${X_CRYPTO_VERSION:-v0.56.0} X_SYS_VERSION=${X_SYS_VERSION:-v0.47.0} CNI_VERSION=${CNI_VERSION:-v1.9.1} CNI_GIT_COMMIT=${CNI_GIT_COMMIT:-adc3e6b5b581638afbd194cf2e9319ecbb0151a1} diff --git a/scripts/validate b/scripts/validate index 9ed7c40..e2b81f6 100644 --- a/scripts/validate +++ b/scripts/validate @@ -16,11 +16,11 @@ grep -Fq 'ARG KUBERNETES_GIT_COMMIT=bb826b1d48562f110659e64e8ec444327433db95' pa grep -Fq 'ARG KUBERNETES_SOURCE_SHA256=3c28f11492472df48e658551bf268fd92938b127b0f9dcef7090ac800318c821' package/Dockerfile grep -Fq 'ARG OPENTELEMETRY_VERSION=v1.45.0' package/Dockerfile grep -Fq 'ARG OPENTELEMETRY_GRPC_VERSION=v0.70.0' package/Dockerfile -grep -Fq 'ARG GRPC_GO_VERSION=v1.83.1' package/Dockerfile +test "$(grep -Fc 'ARG GRPC_GO_VERSION=v1.83.2' package/Dockerfile)" -eq 2 grep -Fq 'ARG CEL_GO_VERSION=v0.32.0' package/Dockerfile grep -Fq 'ARG ETCD_VERSION=v3.7.1' package/Dockerfile grep -Fq 'ARG ETCD_RAFT_VERSION=v3.7.0' package/Dockerfile -grep -Fq 'ARG X_CRYPTO_VERSION=v0.55.0' package/Dockerfile +test "$(grep -Fc 'ARG X_CRYPTO_VERSION=v0.56.0' package/Dockerfile)" -eq 2 grep -Fq 'ARG X_SYS_VERSION=v0.47.0' package/Dockerfile grep -Fq 'ARG CNI_VERSION=v1.9.1' package/Dockerfile grep -Fq 'ARG CNI_GIT_COMMIT=adc3e6b5b581638afbd194cf2e9319ecbb0151a1' package/Dockerfile diff --git a/security/openvex.json b/security/openvex.json index 7354b92..05a74e7 100644 --- a/security/openvex.json +++ b/security/openvex.json @@ -2,7 +2,7 @@ "@context": "https://openvex.dev/ns/v0.2.0", "@id": "https://github.com/PastureStack/kubernetes-package/security/openvex/v1.36.4", "author": "PastureStack Security", - "timestamp": "2026-08-25T00:00:00Z", + "timestamp": "2026-09-09T00:00:00Z", "version": 1, "statements": [ { @@ -11,7 +11,7 @@ }, "products": [ { - "@id": "pkg:golang/golang.org/x/crypto@v0.55.0" + "@id": "pkg:golang/golang.org/x/crypto@v0.56.0" } ], "status": "not_affected",