Skip to content

Commit bbfea76

Browse files
authored
Harden and simplify the release workflow (#4908)
* Always use the Go version specified in the go.mod so the release is always built with the exact Go version specified in go.mod. * Drop packages:write permission No images are pushed to GitHub Container Registry (ghcr.io). * Get rid of Fossa scan during release it is already executed for every relevant push action. * Prepare Docker environment step should be obsolete with GoReleaser Docker v2 engine. * Improve release.yml readability * Prepare GoReleaser for immutable releases by using a draft gh release until the last step. * Pin GoReleaser version to v2.14.3 * Pin tonistiigi/binfmt to a specific version docker/setup-qemu-action defaults to tonistiigi/binfmt:latest, which is a floating Docker Hub tag regardless of the action being SHA-pinned. Pin to an explicit version tag and digest to prevent an attacker from pushing a new :latest image between runs. * Get rid of the manual release trigger because it does not make sense with immutable releases. We have to use forks to not pollute the repo with immutable testing tags. * Replace in-release tests with CI check on tagged commit Instead of re-running unit and integration tests inside the release workflow, query the CI workflow result for the pr of the commit the tag points to. Hotfix commits are pushed directly to a branch without a PR. When no merged PR is found for the tagged commit, verify the CI workflow runs on that commit instead. Hotfix branches follow the pattern *-hotfix-*. CI must run on push so that the release workflow can verify the commit. Release branches require PRs, making the push trigger there redundant, so getting rid of it. Reading PR and Commit CI results requires permissions pull-requests and checks. * Skip known-hosts check on push events GITHUB_BASE_REF is empty on push events; the script exits with a usage error. The known-hosts check is only meaningful in a PR context where a base branch is defined. Also quote the variable to satisfy shellcheck SC2086. * Remove Rancher code freeze verification in release workflow because we should be still able to release and if required, it should be done inside of the release-against-rancher action.
1 parent 1be8722 commit bbfea76

5 files changed

Lines changed: 51 additions & 99 deletions

File tree

.github/workflows/check-changes.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ name: Check for unallowed changes
22

33
on:
44
pull_request:
5+
push:
6+
branches:
7+
- '*-hotfix-*'
58

69
env:
710
MAIN_BRANCH: origin/main
@@ -33,4 +36,5 @@ jobs:
3336
run: ./.github/scripts/check-for-auto-generated-changes.sh
3437
-
3538
name: known-hosts
36-
run: ./.github/scripts/check-for-known-hosts-changes.sh $GITHUB_BASE_REF
39+
if: github.event_name == 'pull_request'
40+
run: ./.github/scripts/check-for-known-hosts-changes.sh "$GITHUB_BASE_REF"

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
pull_request:
77
push:
88
branches:
9-
- 'release/*'
9+
- '*-hotfix-*'
1010

1111
env:
1212
GOARCH: amd64

.github/workflows/e2e-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
pull_request:
66
push:
77
branches:
8-
- 'release/*'
8+
- '*-hotfix-*'
99

1010
env:
1111
GOARCH: amd64

.github/workflows/e2e-multicluster-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
pull_request:
88
push:
99
branches:
10-
- 'release/*'
10+
- '*-hotfix-*'
1111

1212
env:
1313
GOARCH: amd64

.github/workflows/release.yml

Lines changed: 43 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,17 @@ on:
55
push:
66
tags:
77
- v**
8-
workflow_dispatch:
9-
inputs:
10-
tag:
11-
description: 'Tag to release (e.g., v0.15.0-alpha.7)'
12-
required: true
13-
type: string
14-
skip_tests:
15-
description: 'Skip tests (for faster testing of release process)'
16-
required: false
17-
type: boolean
18-
default: false
198

209
permissions:
2110
contents: write
22-
packages: write
2311
id-token: write # this is important, it's how we authenticate with Vault
12+
pull-requests: read
13+
checks: read
2414

2515
env:
2616
GOARCH: amd64
2717
CGO_ENABLED: 0
28-
RELEASE_TAG: ${{ inputs.tag || github.ref_name }}
18+
RELEASE_TAG: ${{ github.ref_name }}
2919

3020
jobs:
3121
build-fleet:
@@ -41,99 +31,56 @@ jobs:
4131
with:
4232
fetch-depth: 0
4333

44-
- name: Verify Rancher is not in code freeze (alpha/beta only)
34+
- name: Verify CI passed on tagged commit
35+
env:
36+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4537
run: |
46-
set -x
47-
FLEET_VERSION="${RELEASE_TAG#v}"
48-
49-
if [[ ! "${FLEET_VERSION}" =~ (alpha|beta) ]]; then
50-
echo "Skipping code freeze check for non-alpha/beta release"
51-
exit 0
52-
fi
53-
54-
FLEET_MINOR=$(echo "${FLEET_VERSION}" | cut -d'.' -f2)
55-
RANCHER_VERSION="2.$((FLEET_MINOR - 1))"
56-
57-
if ! DOCKERFILE_CONTENT=$(curl -sf "https://raw.githubusercontent.com/rancher/rancher/release/v${RANCHER_VERSION}/package/Dockerfile"); then
58-
echo "Release branch release/v${RANCHER_VERSION} not found, assuming main branch which can not be in code freeze"
59-
exit 0
60-
fi
61-
CHART_DEFAULT_BRANCH=$(echo "${DOCKERFILE_CONTENT}" | grep "ARG CHART_DEFAULT_BRANCH=" | cut -d'=' -f2)
62-
63-
if [[ "${CHART_DEFAULT_BRANCH}" != "dev-v${RANCHER_VERSION}" ]]; then
64-
echo "ERROR: CHART_DEFAULT_BRANCH does not match the expected dev branch!"
65-
exit 1
66-
fi
38+
set -euo pipefail
39+
COMMIT_SHA=$(git rev-list -n 1 "$RELEASE_TAG")
40+
echo "Verifying CI checks for ${RELEASE_TAG} (${COMMIT_SHA})"
41+
42+
PR_NUMBER=$(gh api \
43+
"repos/${{ github.repository }}/commits/${COMMIT_SHA}/pulls" \
44+
--jq '[.[] | select(.merged_at != null)] | first | .number // empty')
45+
46+
if [[ -n "${PR_NUMBER:-}" ]]; then
47+
echo "Found PR #${PR_NUMBER}, verifying required checks..."
48+
gh pr checks "${PR_NUMBER}" \
49+
--repo "${{ github.repository }}" \
50+
--required
51+
else
52+
echo "No merged PR found (hotfix), verifying all commit checks..."
53+
ISSUES=$(gh api \
54+
"repos/${{ github.repository }}/commits/${COMMIT_SHA}/check-runs" \
55+
--jq 'if .total_count == 0 then "no CI checks found" else ([.check_runs[] | select(.status != "completed" or (.conclusion != "success" and .conclusion != "skipped")) | .name] | join(", ")) end')
6756
68-
LATEST_RANCHER_RELEASE=$(curl -sf "https://api.github.com/repos/rancher/rancher/releases" | jq -r "[.[] | select(.tag_name | startswith(\"v${RANCHER_VERSION}.\"))] | first | .tag_name")
69-
if [ -z "${LATEST_RANCHER_RELEASE}" ]; then
70-
echo "No Rancher ${RANCHER_VERSION}.x release found, assuming pre-release state"
71-
exit 0
72-
fi
57+
if [[ -n "${ISSUES}" ]]; then
58+
echo "ERROR: ${ISSUES}"
59+
exit 1
60+
fi
7361
74-
if [[ "${LATEST_RANCHER_RELEASE}" =~ -rc ]]; then
75-
echo "ERROR: Latest Rancher ${RANCHER_VERSION}.x release is an RC (${LATEST_RANCHER_RELEASE}), indicating code freeze!"
76-
exit 1
62+
echo "✓ All checks passed for ${RELEASE_TAG} (${COMMIT_SHA})"
7763
fi
7864
7965
- name: Set up Go
8066
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
8167
with:
8268
go-version-file: 'go.mod'
83-
check-latest: true
84-
85-
- name: "Read Vault Secrets"
86-
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
87-
with:
88-
secrets: |
89-
secret/data/github/repo/${{ github.repository }}/fossa/credential token | FOSSA_API_KEY
90-
91-
- name: Run FOSSA scan
92-
if: ${{ !inputs.skip_tests }}
93-
uses: fossas/fossa-action@c414b9ad82eaad041e47a7cf62a4f02411f427a0 # v1.8.0
94-
with:
95-
api-key: ${{ env.FOSSA_API_KEY }}
96-
97-
- name: Run FOSSA tests
98-
if: ${{ !inputs.skip_tests }}
99-
uses: fossas/fossa-action@c414b9ad82eaad041e47a7cf62a4f02411f427a0 # v1.8.0
100-
with:
101-
api-key: ${{ env.FOSSA_API_KEY }}
102-
run-tests: false
103-
104-
- name: Install Ginkgo CLI
105-
if: ${{ !inputs.skip_tests }}
106-
run: go install github.com/onsi/ginkgo/v2/ginkgo
107-
108-
- name: Check for code changes
109-
if: ${{ !inputs.skip_tests }}
110-
continue-on-error: ${{ contains(github.ref, 'rc') }}
111-
run: |
112-
./.github/scripts/check-for-auto-generated-changes.sh
113-
go mod verify
114-
115-
- name: Run unit tests
116-
if: ${{ !inputs.skip_tests }}
117-
continue-on-error: ${{ contains(github.ref, 'rc') }}
118-
run: go list ./... | grep -v -e /e2e -e /integrationtests -e /benchmarks | xargs go test -cover -tags=test
119-
120-
- name: Run integration tests
121-
if: ${{ !inputs.skip_tests }}
122-
continue-on-error: ${{ contains(github.ref, 'rc') }}
123-
env:
124-
SETUP_ENVTEST_VER: v0.0.0-20250218120612-6f6111124902
125-
ENVTEST_K8S_VERSION: 1.35
126-
run: ./.github/scripts/run-integration-tests.sh
12769

12870
- name: Set up QEMU
12971
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
72+
with:
73+
# renovate: datasource=docker depName=tonistiigi/binfmt extractVersion=^qemu-v(?<version>.+)$
74+
image: tonistiigi/binfmt:qemu-v10.2.1-65@sha256:d3b963f787999e6c0219a48dba02978769286ff61a5f4d26245cb6a6e5567ea3
13075

13176
- name: Set up Docker Buildx
13277
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
13378

13479
- name: Install Cosign
13580
uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0
136-
- uses: rancherlabs/slsactl/actions/install-slsactl@3dc09f73d4b3a03fbb87eff19ed0262c231d8757 # v0.1.22
81+
82+
- name: Install Slsactl
83+
uses: rancherlabs/slsactl/actions/install-slsactl@3dc09f73d4b3a03fbb87eff19ed0262c231d8757 # v0.1.22
13784
with:
13885
version: v0.1.22
13986

@@ -148,11 +95,6 @@ jobs:
14895
secret/data/github/repo/${{ github.repository }}/rancher-prime-stg-registry/credentials registry | STAGE_REGISTRY ;
14996
secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials registry | PRIME_REGISTRY ;
15097
151-
- name: Prepare Docker environment to support sbom/provenance parameters
152-
run: |
153-
sudo bash -c 'echo "{\"features\": {\"containerd-snapshotter\": true}}" > /etc/docker/daemon.json'
154-
sudo systemctl restart docker
155-
15698
- name: Log into Docker Container registry
15799
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
158100
if: ${{ env.IS_HOTFIX == 'false' }}
@@ -172,8 +114,8 @@ jobs:
172114
id: goreleaser
173115
with:
174116
distribution: goreleaser
175-
version: '~> v2'
176-
args: release --clean --verbose
117+
version: v2.14.3
118+
args: release --clean --draft --verbose
177119
env:
178120
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179121
GORELEASER_CURRENT_TAG: ${{ env.RELEASE_TAG }}
@@ -317,3 +259,9 @@ jobs:
317259
318260
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git"
319261
git push origin "$charts_branch"
262+
263+
- name: Publish Release
264+
if: ${{ env.IS_HOTFIX == 'false' }}
265+
run: gh release edit "${RELEASE_TAG}" --draft=false
266+
env:
267+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)