Skip to content

Commit e6bd578

Browse files
committed
pre-release workflow
1 parent c893a8e commit e6bd578

File tree

5 files changed

+248
-0
lines changed

5 files changed

+248
-0
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@
1212

1313
**Which issue(s) this PR fixes:** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*
1414
Fixes #
15+
16+
<!-- In case of the change being user-facing, an entry should be appended to the latest unreleased section in CHANGELOG.md.
17+
The expected format is as follows:
18+
- [ENHANCEMENT/CHANGE/BUGFIX/FEATURE]: <PR TITLE> by @PR_AUTHOR in https://github.com/kubernetes/kube-state-metrics/pull/<PR NUMBER> (avoid using #<PR NUMBER> for inter-VCS compatibility), for instance:
19+
- [ENHANCEMENT]: Add support for Windows by @k8s-ci-robot in https://github.com/kubernetes/kube-state-metrics/pull/1234
20+
-->
21+
- [ ] I have added a CHANGELOG entry for this change.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
name: Pre-Release PR
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
new_version:
7+
description: 'The new release version (e.g., v2.10.0)'
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
15+
env:
16+
GO_VERSION: "^1.24.6"
17+
GOLANGCI_LINT_VERSION: "v2.4.0"
18+
E2E_SETUP_KIND: yes
19+
E2E_SETUP_KUBECTL: yes
20+
21+
jobs:
22+
release:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Validate version format
26+
run: |
27+
if [[ ! "${{ inputs.new_version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
28+
echo "Error: Version format is incorrect. It must be in the format 'vX.Y.Z'."
29+
exit 1
30+
fi
31+
echo "Version format is valid."
32+
- name: Checkout into the corresponding release branch
33+
uses: actions/checkout@v4
34+
- name: Checkout to release branch
35+
run: |
36+
git checkout -b prep-${{ inputs.new_version }}
37+
MAJOR_MINOR_VERSION=$(echo "${{ inputs.new_version }}" | sed 's/^v//' | cut -d. -f1,2)
38+
if git show-ref --verify --quiet refs/remotes/origin/release-$MAJOR_MINOR_VERSION; then
39+
echo "Release branch release-$MAJOR_MINOR_VERSION already exists, switching to it"
40+
git checkout -b release-$MAJOR_MINOR_VERSION origin/release-$MAJOR_MINOR_VERSION
41+
else
42+
echo "Creating new release branch release-$MAJOR_MINOR_VERSION"
43+
git checkout -b release-$MAJOR_MINOR_VERSION
44+
git push origin release-$MAJOR_MINOR_VERSION
45+
fi
46+
git checkout prep-${{ inputs.new_version }}
47+
- name: Set up the go@${{ env.GO_VERSION }} environment
48+
uses: actions/setup-go@v5
49+
with:
50+
go-version: ${{ env.GO_VERSION }}
51+
- name: Update the VERSION manifest
52+
run: echo "${{ inputs.new_version }}" | sed 's/^v//' > VERSION
53+
- name: Update data.yaml
54+
run: ./scripts/update-data-yaml.sh "${{ inputs.new_version }}"
55+
- name: Update the compatibility matrix (README.md)
56+
run: make generate
57+
- name: Move unreleased to released in CHANGELOG.md
58+
run: ./scripts/generate-release-date.sh "${{ inputs.new_version }}"
59+
- name: make lint-fix
60+
run: |
61+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | \
62+
sh -s -- -b $(go env GOPATH)/bin ${{ env.GOLANGCI_LINT_VERSION }}
63+
make lint-fix
64+
- name: Generate manifests
65+
run: |
66+
make clean || true
67+
VERSION="${{ inputs.new_version }}" make examples
68+
- name: Update the remote and commit the changes
69+
run: |
70+
git config --local user.email "${{ github.actor }}@users.noreply.github.com"
71+
git config --local user.name "${{ github.actor }}"
72+
git add .
73+
git commit -m "chore: Cut ${{ inputs.new_version }}"
74+
git push origin prep-${{ inputs.new_version }}
75+
- name: Validate docs
76+
run: make doccheck
77+
- name: Validate manifests
78+
run: make validate-manifests
79+
- name: Validate go modules
80+
run: make validate-modules
81+
- name: Run rule tests
82+
run: PROMTOOL_CLI=./promtool make install-promtool test-rules
83+
- name: Run unit tests
84+
run: make test-unit
85+
- name: Run end-to-end tests
86+
run: |
87+
make e2e
88+
find examples -name "*.yaml" -type f -exec sed -i 's|kube-state-metrics-amd64|kube-state-metrics|g; s|kube-state-metrics-arm64|kube-state-metrics|g' {} \;
89+
- name: Run benchmark tests
90+
run: |
91+
BENCHSTAT_OUTPUT_FILE=result.txt ./tests/compare_benchmarks.sh main 2
92+
- name: Post results to job summary
93+
run: |
94+
echo "### Benchmark Comparison Results" >> "$GITHUB_STEP_SUMMARY"
95+
echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY"
96+
cat result.txt >> "$GITHUB_STEP_SUMMARY"
97+
echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY"
98+
- name: Create a pull request
99+
run: |
100+
# Extract major.minor version for branch naming
101+
MAJOR_MINOR_VERSION=$(echo "${{ inputs.new_version }}" | sed 's/^v//' | cut -d. -f1,2)
102+
103+
# Get the most recent tag for changelog generation
104+
PREV_TAG=$(git tag --sort=-version:refname | head -n1 || echo "")
105+
106+
# Determine date range for PR search
107+
if [[ -n "$PREV_TAG" ]]; then
108+
PREV_TAG_DATE="$(git show -s --format=%cI "$PREV_TAG" 2>/dev/null || true)"
109+
RANGE="${PREV_TAG}..HEAD"
110+
else
111+
PREV_TAG_DATE="1970-01-01T00:00:00Z"
112+
PREV_REF="$(git rev-list --max-parents=0 HEAD)"
113+
RANGE="${PREV_REF}..HEAD"
114+
fi
115+
116+
# Format dates for PR search
117+
PREV_DATE_SHORT="$(date -d "$PREV_TAG_DATE" +%Y-%m-%d 2>/dev/null || echo "1970-01-01")"
118+
TAG_DATE_SHORT="$(date -u +%Y-%m-%d)"
119+
120+
# Extract changelog section for this version
121+
CHANGELOG_SECTION=$(awk '/^## '"${{ inputs.new_version }}"'/{flag=1; next} /^## /{if(flag) exit} flag' CHANGELOG.md | \
122+
grep -E '^\s*\*\s*\[' | \
123+
sed 's/^/ /' || \
124+
echo " No user-facing changes found for this version.")
125+
126+
# Get merged PRs in the date range
127+
PR_LINES="$(gh pr list \
128+
--state merged \
129+
--search "merged:${PREV_DATE_SHORT}..${TAG_DATE_SHORT}" \
130+
--json number,title,author \
131+
--limit 1000 \
132+
--template '{{range .}}{{.number}}|{{.title}}|{{.author.login}}{{"\n"}}{{end}}')" || true
133+
134+
# Build full changelog from merged PRs
135+
FULL_CHANGELOG_LINES=()
136+
if [[ -n "$PR_LINES" ]]; then
137+
while IFS= read -r line; do
138+
if [[ -n "$line" ]]; then
139+
prnum="${line%%|*}"
140+
rest="${line#*|}"
141+
title="${rest%%|*}"
142+
login="${rest##*|}"
143+
FULL_CHANGELOG_LINES+=(" - ${title} by @${login} in #${prnum}")
144+
fi
145+
done <<< "$PR_LINES"
146+
fi
147+
148+
# Format full changelog text
149+
FULL_CHANGELOG_TEXT=""
150+
if [[ ${#FULL_CHANGELOG_LINES[@]} -gt 0 ]]; then
151+
printf -v FULL_CHANGELOG_TEXT "%s\n" "${FULL_CHANGELOG_LINES[@]}"
152+
else
153+
FULL_CHANGELOG_TEXT=" (no merged PRs found in this release)"
154+
fi
155+
156+
# Create PR body file to avoid quote issues
157+
cat > pr_body.txt << EOF
158+
This PR was automatically created by the release workflow.
159+
160+
## Changelog
161+
162+
$CHANGELOG_SECTION
163+
164+
## Full Changelog
165+
166+
$FULL_CHANGELOG_TEXT
167+
EOF
168+
169+
# Create the pull request
170+
gh pr create \
171+
--title "chore: Cut ${{ inputs.new_version }}" \
172+
--body-file pr_body.txt \
173+
--base release-$MAJOR_MINOR_VERSION \
174+
--head prep-${{ inputs.new_version }} \
175+
--reviewer @sig-instrumentation-approvers \
176+
--assignee @sig-instrumentation-leads
177+
178+
# Clean up temporary file
179+
rm pr_body.txt
180+
env:
181+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,5 @@ help.txt
4343

4444
# jsonnet dependency management
4545
/scripts/vendor
46+
47+
promtool

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
## Released
6+
37
## v2.17.0 / 2025-09-01
48

59
* This release builds with Go `v1.24.6`

scripts/generate-release-date.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/bash
2+
set -exuo pipefail
3+
4+
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
5+
REPO_ROOT=$( cd -- "${SCRIPT_DIR}/.." &> /dev/null && pwd )
6+
CHANGELOG_FILE="${REPO_ROOT}/CHANGELOG.md"
7+
8+
if [ -z "$1" ]; then
9+
echo "Error: A version argument is required (e.g., v2.10.0)." >&2
10+
exit 1
11+
fi
12+
new_version=$1
13+
14+
# Determine the OS to use the correct version of sed.
15+
# shellcheck disable=SC2209
16+
SED=sed
17+
if [[ $(uname) == "Darwin" ]]; then
18+
# Check if gnu-sed is installed.
19+
if ! command -v gsed &> /dev/null; then
20+
echo "gnu-sed is not installed. Please install it using 'brew install gnu-sed'." >&2
21+
exit 1
22+
fi
23+
SED=gsed
24+
fi
25+
26+
# Extract content between "## Unreleased" and "## Released"
27+
UNRELEASED_CONTENT=$($SED -n '/^## Unreleased/,/^## Released/{/^## Unreleased/d; /^## Released/d; p;}' "${CHANGELOG_FILE}")
28+
29+
# Clear the Unreleased section (remove everything between "## Unreleased" and "## Released")
30+
$SED -i '/^## Unreleased/,/^## Released/{/^## Unreleased/!{/^## Released/!d;}}' "${CHANGELOG_FILE}"
31+
32+
# Add an empty line after the Unreleased section
33+
$SED -i '/^## Unreleased/a\\' "${CHANGELOG_FILE}"
34+
35+
# Add the new version section with date after "## Released"
36+
if [[ -n "$UNRELEASED_CONTENT" ]]; then
37+
# Create a temporary file to avoid issues with quotes and special characters
38+
TEMP_FILE=$(mktemp)
39+
echo "" > "$TEMP_FILE"
40+
echo "## $new_version / $(date +'%Y-%m-%d')" >> "$TEMP_FILE"
41+
echo "" >> "$TEMP_FILE"
42+
echo "$UNRELEASED_CONTENT" >> "$TEMP_FILE"
43+
44+
$SED -i "/^## Released/r $TEMP_FILE" "${CHANGELOG_FILE}"
45+
46+
rm "$TEMP_FILE"
47+
else
48+
# If no content in Unreleased, just add the version header
49+
$SED -i "/^## Released/a\\
50+
\\
51+
## $new_version / $(date +'%Y-%m-%d')" "${CHANGELOG_FILE}"
52+
fi
53+
54+
echo "CHANGELOG.md updated successfully. Moved unreleased content to $new_version section."

0 commit comments

Comments
 (0)