Skip to content

Commit c70d9d1

Browse files
committed
ci: gate releases from main
1 parent b418c35 commit c70d9d1

8 files changed

Lines changed: 301 additions & 56 deletions

File tree

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Release Gate
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
paths:
7+
- 'src/**'
8+
- 'tests/**'
9+
- 'Cargo.toml'
10+
- 'Cargo.lock'
11+
- 'Dockerfile'
12+
- 'deploy/**'
13+
- 'CHANGELOG.md'
14+
- 'scripts/release-gate.sh'
15+
- '.github/workflows/**'
16+
push:
17+
branches: [main]
18+
paths:
19+
- 'src/**'
20+
- 'tests/**'
21+
- 'Cargo.toml'
22+
- 'Cargo.lock'
23+
- 'Dockerfile'
24+
- 'deploy/**'
25+
- 'CHANGELOG.md'
26+
- 'scripts/release-gate.sh'
27+
- '.github/workflows/**'
28+
workflow_dispatch:
29+
30+
permissions:
31+
contents: read
32+
33+
env:
34+
CARGO_TERM_COLOR: always
35+
RUST_BACKTRACE: 1
36+
37+
jobs:
38+
release-gate:
39+
name: Validate Release Candidate
40+
runs-on: ubuntu-latest
41+
steps:
42+
- name: Checkout repository
43+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
44+
with:
45+
persist-credentials: false
46+
fetch-depth: 0
47+
fetch-tags: true
48+
49+
- name: Install Rust toolchain
50+
uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
51+
with:
52+
toolchain: stable
53+
components: clippy, rustfmt
54+
55+
- name: Install Helm
56+
uses: azure/setup-helm@v4.2.0
57+
with:
58+
version: v3.14.4
59+
60+
- name: Cache cargo registry
61+
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
62+
with:
63+
path: |
64+
~/.cargo/registry
65+
~/.cargo/git
66+
target
67+
key: ${{ runner.os }}-cargo-release-gate-${{ hashFiles('**/Cargo.lock') }}
68+
restore-keys: |
69+
${{ runner.os }}-cargo-release-gate-
70+
${{ runner.os }}-cargo-
71+
72+
- name: Validate release metadata
73+
run: bash scripts/release-gate.sh
74+
75+
- name: Check formatting
76+
run: cargo fmt --all -- --check
77+
78+
- name: Run clippy
79+
run: cargo clippy --all-targets --all-features -- -D warnings
80+
81+
- name: Run tests
82+
run: cargo test --all-features
83+
env:
84+
RUST_LOG: debug
85+
86+
- name: Generate CRDs
87+
run: cargo run --bin crdgen
88+
89+
- name: Verify CRDs are up to date
90+
run: |
91+
git diff --exit-code deploy/crds/ deploy/helm/strimzi-backup-operator/crds/
92+
cmp deploy/crds/kafkabackups.yaml deploy/helm/strimzi-backup-operator/crds/kafkabackups.yaml
93+
cmp deploy/crds/kafkarestores.yaml deploy/helm/strimzi-backup-operator/crds/kafkarestores.yaml
94+
95+
- name: Lint Helm chart
96+
run: helm lint deploy/helm/strimzi-backup-operator
97+
98+
- name: Render Helm chart with defaults
99+
run: |
100+
APP_VERSION=$(awk '$1 == "appVersion:" { gsub(/"/, "", $2); print $2; exit }' deploy/helm/strimzi-backup-operator/Chart.yaml)
101+
helm template strimzi-backup-operator deploy/helm/strimzi-backup-operator \
102+
| tee /tmp/strimzi-backup-operator-default.yaml
103+
grep -q 'name: BACKUP_JOB_SERVICE_ACCOUNT' /tmp/strimzi-backup-operator-default.yaml
104+
grep -q 'value: "strimzi-backup-operator"' /tmp/strimzi-backup-operator-default.yaml
105+
grep -q "image: ghcr.io/osodevops/strimzi-backup-operator:${APP_VERSION}" /tmp/strimzi-backup-operator-default.yaml
106+
107+
- name: Render Helm chart with backup job service account override
108+
run: |
109+
helm template strimzi-backup-operator deploy/helm/strimzi-backup-operator \
110+
--set backupJobs.serviceAccountName=kafka-backup-operator \
111+
| tee /tmp/strimzi-backup-operator-override.yaml
112+
grep -q 'value: "kafka-backup-operator"' /tmp/strimzi-backup-operator-override.yaml

.github/workflows/release.yaml

Lines changed: 92 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@ name: Release
22

33
on:
44
push:
5-
tags:
6-
- 'v[0-9]+.[0-9]+.[0-9]+'
7-
- 'v[0-9]+.[0-9]+.[0-9]+-*'
5+
branches:
6+
- main
7+
paths:
8+
- 'src/**'
9+
- 'tests/**'
10+
- 'Cargo.toml'
11+
- 'Cargo.lock'
12+
- 'Dockerfile'
13+
- 'deploy/**'
14+
- 'CHANGELOG.md'
15+
- 'scripts/release-gate.sh'
16+
- '.github/workflows/release.yaml'
17+
- '.github/workflows/sync-helm-chart.yaml'
18+
workflow_dispatch:
819

920
env:
1021
REGISTRY: ghcr.io
@@ -20,28 +31,50 @@ jobs:
2031
runs-on: ubuntu-latest
2132
outputs:
2233
version: ${{ steps.version.outputs.version }}
34+
tag: ${{ steps.version.outputs.tag }}
35+
docker_tags: ${{ steps.version.outputs.docker_tags }}
2336
steps:
2437
- name: Checkout repository
2538
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2639
with:
2740
persist-credentials: false
41+
fetch-depth: 0
42+
fetch-tags: true
2843

29-
- name: Extract version from tag
44+
- name: Extract release version
3045
id: version
3146
run: |
32-
VERSION=${GITHUB_REF#refs/tags/v}
47+
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
48+
VERSION="${GITHUB_REF#refs/tags/v}"
49+
else
50+
VERSION=$(awk -F '"' '/^version = / { print $2; exit }' Cargo.toml)
51+
fi
52+
53+
TAG="v${VERSION}"
54+
MAJOR="${VERSION%%.*}"
55+
REST="${VERSION#*.}"
56+
MINOR="${REST%%.*}"
57+
MAJOR_MINOR="${MAJOR}.${MINOR}"
58+
3359
echo "version=$VERSION" >> $GITHUB_OUTPUT
60+
echo "tag=$TAG" >> $GITHUB_OUTPUT
61+
{
62+
echo "docker_tags<<EOF"
63+
echo "${REGISTRY}/${IMAGE_NAME}:${VERSION}"
64+
if [[ "$VERSION" != *-* ]]; then
65+
echo "${REGISTRY}/${IMAGE_NAME}:${MAJOR_MINOR}"
66+
echo "${REGISTRY}/${IMAGE_NAME}:${MAJOR}"
67+
echo "${REGISTRY}/${IMAGE_NAME}:latest"
68+
fi
69+
echo "EOF"
70+
} >> $GITHUB_OUTPUT
3471
echo "Release version: $VERSION"
3572
36-
- name: Verify Cargo.toml version matches tag
37-
run: |
38-
CARGO_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
39-
TAG_VERSION=${GITHUB_REF#refs/tags/v}
40-
if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
41-
echo "Error: Cargo.toml version ($CARGO_VERSION) does not match tag version ($TAG_VERSION)"
42-
exit 1
43-
fi
44-
echo "Version verified: $CARGO_VERSION"
73+
- name: Validate release gate
74+
env:
75+
EXPECTED_VERSION: ${{ steps.version.outputs.version }}
76+
ALLOW_EXISTING_TAG: ${{ startsWith(github.ref, 'refs/tags/') }}
77+
run: bash scripts/release-gate.sh
4578

4679
test:
4780
name: Pre-release Tests
@@ -59,6 +92,11 @@ jobs:
5992
toolchain: stable
6093
components: clippy, rustfmt
6194

95+
- name: Install Helm
96+
uses: azure/setup-helm@v4.2.0
97+
with:
98+
version: v3.14.4
99+
62100
- name: Cache cargo registry
63101
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
64102
with:
@@ -81,6 +119,31 @@ jobs:
81119
env:
82120
RUST_LOG: debug
83121

122+
- name: Generate CRDs
123+
run: cargo run --bin crdgen
124+
125+
- name: Verify CRDs are up to date
126+
run: |
127+
git diff --exit-code deploy/crds/ deploy/helm/strimzi-backup-operator/crds/
128+
cmp deploy/crds/kafkabackups.yaml deploy/helm/strimzi-backup-operator/crds/kafkabackups.yaml
129+
cmp deploy/crds/kafkarestores.yaml deploy/helm/strimzi-backup-operator/crds/kafkarestores.yaml
130+
131+
- name: Lint Helm chart
132+
run: helm lint deploy/helm/strimzi-backup-operator
133+
134+
- name: Render Helm chart
135+
run: |
136+
APP_VERSION=$(awk '$1 == "appVersion:" { gsub(/"/, "", $2); print $2; exit }' deploy/helm/strimzi-backup-operator/Chart.yaml)
137+
helm template strimzi-backup-operator deploy/helm/strimzi-backup-operator \
138+
| tee /tmp/strimzi-backup-operator-default.yaml
139+
grep -q 'name: BACKUP_JOB_SERVICE_ACCOUNT' /tmp/strimzi-backup-operator-default.yaml
140+
grep -q 'value: "strimzi-backup-operator"' /tmp/strimzi-backup-operator-default.yaml
141+
grep -q "image: ghcr.io/osodevops/strimzi-backup-operator:${APP_VERSION}" /tmp/strimzi-backup-operator-default.yaml
142+
helm template strimzi-backup-operator deploy/helm/strimzi-backup-operator \
143+
--set backupJobs.serviceAccountName=kafka-backup-operator \
144+
| tee /tmp/strimzi-backup-operator-override.yaml
145+
grep -q 'value: "kafka-backup-operator"' /tmp/strimzi-backup-operator-override.yaml
146+
84147
build-and-push:
85148
name: Build and Push Docker Image
86149
runs-on: ubuntu-latest
@@ -104,17 +167,6 @@ jobs:
104167
username: ${{ github.actor }}
105168
password: ${{ secrets.GITHUB_TOKEN }}
106169

107-
- name: Extract metadata for Docker
108-
id: meta
109-
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
110-
with:
111-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
112-
tags: |
113-
type=semver,pattern={{version}}
114-
type=semver,pattern={{major}}.{{minor}}
115-
type=semver,pattern={{major}}
116-
type=raw,value=latest
117-
118170
- name: Build Docker image
119171
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
120172
with:
@@ -136,8 +188,7 @@ jobs:
136188
context: .
137189
platforms: linux/amd64,linux/arm64
138190
push: true
139-
tags: ${{ steps.meta.outputs.tags }}
140-
labels: ${{ steps.meta.outputs.labels }}
191+
tags: ${{ needs.validate.outputs.docker_tags }}
141192
cache-from: type=gha
142193
cache-to: type=gha,mode=max
143194

@@ -179,41 +230,41 @@ jobs:
179230
- name: Generate changelog
180231
id: changelog
181232
run: |
182-
TAG="${GITHUB_REF#refs/tags/}"
233+
TAG="${{ needs.validate.outputs.tag }}"
183234
184235
# Find the previous tag for changelog generation
185-
PREV_TAG=$(git tag --sort=-v:refname | grep -A1 "^${TAG}$" | tail -1)
186-
if [ "$PREV_TAG" = "$TAG" ] || [ -z "$PREV_TAG" ]; then
236+
PREV_TAG=$(git tag --sort=-v:refname | grep -v "^${TAG}$" | head -1)
237+
if [ -z "$PREV_TAG" ]; then
187238
PREV_TAG=$(git rev-list --max-parents=0 HEAD | head -1)
188239
fi
189-
echo "Generating changelog: ${PREV_TAG}..${TAG}"
240+
echo "Generating changelog: ${PREV_TAG}..HEAD"
190241
191242
# Generate changelog grouped by conventional commit type
192243
echo "## What's Changed" > changelog.md
193244
echo "" >> changelog.md
194245
195-
FEATURES=$(git log "${PREV_TAG}..${TAG}" --oneline --grep="^feat" --format="* %s" 2>/dev/null | head -20)
246+
FEATURES=$(git log "${PREV_TAG}..HEAD" --oneline --grep="^feat" --format="* %s" 2>/dev/null | head -20)
196247
if [ -n "$FEATURES" ]; then
197248
echo "### Features" >> changelog.md
198249
echo "$FEATURES" >> changelog.md
199250
echo "" >> changelog.md
200251
fi
201252
202-
FIXES=$(git log "${PREV_TAG}..${TAG}" --oneline --grep="^fix" --format="* %s" 2>/dev/null | head -20)
253+
FIXES=$(git log "${PREV_TAG}..HEAD" --oneline --grep="^fix" --format="* %s" 2>/dev/null | head -20)
203254
if [ -n "$FIXES" ]; then
204255
echo "### Fixes" >> changelog.md
205256
echo "$FIXES" >> changelog.md
206257
echo "" >> changelog.md
207258
fi
208259
209-
DEPS=$(git log "${PREV_TAG}..${TAG}" --oneline --grep="^deps\|^dep\|^chore(deps)\|Bump" --format="* %s" 2>/dev/null | head -20)
260+
DEPS=$(git log "${PREV_TAG}..HEAD" --oneline --grep="^deps\|^dep\|^chore(deps)\|Bump" --format="* %s" 2>/dev/null | head -20)
210261
if [ -n "$DEPS" ]; then
211262
echo "### Dependencies" >> changelog.md
212263
echo "$DEPS" >> changelog.md
213264
echo "" >> changelog.md
214265
fi
215266
216-
OTHER=$(git log "${PREV_TAG}..${TAG}" --oneline --grep="^ci\|^chore\|^style\|^refactor" --format="* %s" 2>/dev/null | head -20)
267+
OTHER=$(git log "${PREV_TAG}..HEAD" --oneline --grep="^ci\|^chore\|^style\|^refactor" --format="* %s" 2>/dev/null | head -20)
217268
if [ -n "$OTHER" ]; then
218269
echo "### Other" >> changelog.md
219270
echo "$OTHER" >> changelog.md
@@ -226,24 +277,19 @@ jobs:
226277
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
227278
with:
228279
name: v${{ needs.validate.outputs.version }}
280+
tag_name: ${{ needs.validate.outputs.tag }}
281+
target_commitish: ${{ github.sha }}
229282
body_path: changelog.md
230283
files: |
231284
crds.yaml
232285
draft: false
233-
prerelease: ${{ contains(github.ref, '-') }}
286+
prerelease: ${{ contains(needs.validate.outputs.version, '-') }}
234287
generate_release_notes: false
235288
env:
236289
GITHUB_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
237290

238291
sync-helm-chart:
239-
name: Trigger Helm Chart Sync
240-
runs-on: ubuntu-latest
292+
name: Sync Helm Chart
241293
needs: [create-release]
242-
steps:
243-
- name: Trigger helm-charts repo workflow
244-
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4
245-
with:
246-
token: ${{ secrets.HELM_CHARTS_PAT }}
247-
repository: osodevops/helm-charts
248-
event-type: update-kafka-backup-operator
249-
client-payload: '{"version": "${{ needs.validate.outputs.version }}"}'
294+
uses: ./.github/workflows/sync-helm-chart.yaml
295+
secrets: inherit

.github/workflows/sync-helm-chart.yaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ permissions:
44
contents: read
55

66
on:
7-
push:
8-
branches:
9-
- main
10-
paths:
11-
- 'deploy/helm/strimzi-backup-operator/**'
7+
workflow_call:
128
workflow_dispatch:
139

1410
env:

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
## Unreleased
5+
## 0.2.2 - 2026-04-28
66

77
### Fixed
88

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "kafka-backup-operator"
3-
version = "0.2.1"
3+
version = "0.2.2"
44
edition = "2021"
55
rust-version = "1.88"
66
license = "Apache-2.0"

0 commit comments

Comments
 (0)