Skip to content

Commit aa302aa

Browse files
committed
chore: add prepare-release.yml workflow
1 parent e8da041 commit aa302aa

1 file changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
name: Prepare Release 1.x
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
release_version:
7+
description: "Release version (format: 1.X.Y)"
8+
required: false
9+
default: ""
10+
type: string
11+
swagger_codegen_version:
12+
description: "swagger-codegen release version to pin (e.g. 3.0.79)"
13+
required: true
14+
type: string
15+
16+
permissions:
17+
contents: write
18+
pull-requests: write
19+
20+
jobs:
21+
prepare:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v6
26+
with:
27+
ref: master
28+
fetch-depth: 0
29+
30+
- name: Set up Java 17
31+
uses: actions/setup-java@v5
32+
with:
33+
java-version: "17"
34+
distribution: temurin
35+
cache: maven
36+
overwrite-settings: false
37+
38+
- name: Add Central-Portal snapshot repo to settings.xml
39+
uses: s4u/maven-settings-action@v4.0.0
40+
with:
41+
repositories: '[{"id":"central-portal-snapshots","name":"Sonatype Central Portal snapshots","url":"https://central.sonatype.com/repository/maven-snapshots/","releases":{"enabled":false},"snapshots":{"enabled":true}}]'
42+
servers: '[{"id":"central","username":"${{ secrets.MAVEN_CENTRAL_USERNAME }}","password":"${{ secrets.MAVEN_CENTRAL_PASSWORD }}"}]'
43+
44+
- name: Resolve and validate inputs
45+
id: resolve
46+
run: |
47+
set -euo pipefail
48+
POM_VERSION="$(mvn -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec)"
49+
POM_RELEASE_VERSION="${POM_VERSION%-SNAPSHOT}"
50+
51+
RELEASE_VERSION="${{ inputs.release_version }}"
52+
if [ -z "${RELEASE_VERSION}" ]; then
53+
RELEASE_VERSION="${POM_RELEASE_VERSION}"
54+
fi
55+
if [[ ! "$RELEASE_VERSION" =~ ^1\.[0-9]+\.[0-9]+$ ]]; then
56+
echo "release_version must match 1.X.Y"
57+
exit 1
58+
fi
59+
60+
SWAGGER_CODEGEN_VERSION="${{ inputs.swagger_codegen_version }}"
61+
62+
if [[ "$SWAGGER_CODEGEN_VERSION" =~ SNAPSHOT$ ]]; then
63+
echo "Release dependency versions must not be SNAPSHOT: $SWAGGER_CODEGEN_VERSION"
64+
exit 1
65+
fi
66+
67+
echo "release_version=${RELEASE_VERSION}" >> "$GITHUB_OUTPUT"
68+
echo "swagger_codegen_version=${SWAGGER_CODEGEN_VERSION}" >> "$GITHUB_OUTPUT"
69+
70+
- name: Update versions
71+
run: |
72+
set -euo pipefail
73+
RELEASE_VERSION="${{ steps.resolve.outputs.release_version }}"
74+
SWAGGER_CODEGEN_VERSION="${{ steps.resolve.outputs.swagger_codegen_version }}"
75+
76+
mvn -q -B versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false
77+
if [ -n "${SWAGGER_CODEGEN_VERSION}" ]; then
78+
mvn -q -B versions:set-property -Dproperty=swagger-codegen-version -DnewVersion="${SWAGGER_CODEGEN_VERSION}" -DgenerateBackupPoms=false
79+
fi
80+
81+
- name: Build release candidate
82+
run: |
83+
set -euo pipefail
84+
CODEGEN_VERSION="${{ steps.resolve.outputs.swagger_codegen_version }}"
85+
CODEGEN_MAJOR="${CODEGEN_VERSION%%.*}"
86+
CODEGEN_VERSION_PROPERTY=""
87+
CODEGEN_FOUND_JSON="$(curl -s --max-time 60 --retry 15 --connect-timeout 20 "https://central.sonatype.com/solrsearch/select?q=g:io.swagger.codegen.v3%20AND%20a:swagger-codegen%20AND%20v:${CODEGEN_VERSION}%20AND%20p:jar")"
88+
CODEGEN_FOUND="$(echo "${CODEGEN_FOUND_JSON}" | jq '.response.numFound')"
89+
if [[ "${CODEGEN_FOUND}" == "0" ]]; then
90+
SNAP_API="https://central.sonatype.com/repository/maven-snapshots"
91+
ARTIFACT_PATH="io/swagger/codegen/v3/swagger-codegen"
92+
ROOT_META="${SNAP_API}/${ARTIFACT_PATH}/maven-metadata.xml"
93+
LAST_SNAP="$(curl -s "$ROOT_META" | grep -oP "(?<=<version>)${CODEGEN_MAJOR}\.[^<]+" | sort -V | tail -n1)"
94+
CODEGEN_VERSION_PROPERTY="-Dswagger-codegen-version=${LAST_SNAP}"
95+
fi
96+
./mvnw clean verify -U ${CODEGEN_VERSION_PROPERTY}
97+
98+
- name: Prepare draft release notes body
99+
id: notes
100+
run: |
101+
set -euo pipefail
102+
RELEASE_VERSION="${{ steps.resolve.outputs.release_version }}"
103+
LAST_TAG_VERSION="$(
104+
{
105+
git tag -l 'v1.*' | sed 's/^v//'
106+
echo "${RELEASE_VERSION}"
107+
} \
108+
| grep -E '^1\.[0-9]+\.[0-9]+$' \
109+
| sort -V \
110+
| awk -v rel="${RELEASE_VERSION}" '
111+
$0 == rel { print prev; found=1; exit }
112+
{ prev=$0 }
113+
END { if (!found) exit 1 }
114+
'
115+
)"
116+
if [ -z "${LAST_TAG_VERSION}" ]; then
117+
echo "No previous v1.* tag found before ${RELEASE_VERSION}"
118+
exit 1
119+
fi
120+
LAST_TAG="v${LAST_TAG_VERSION}"
121+
RELEASE_TAG="v${{ steps.resolve.outputs.release_version }}"
122+
NOTES_FILE="${RUNNER_TEMP}/release-notes-${RELEASE_TAG}.md"
123+
{
124+
echo "## ${RELEASE_TAG}"
125+
echo
126+
echo "### Notable Changes"
127+
git log \
128+
--first-parent \
129+
--pretty='- %s (%h)' \
130+
--invert-grep \
131+
--grep='^chore: prepare release ' \
132+
--grep='^chore: bump snapshot to ' \
133+
"${LAST_TAG}..HEAD"
134+
echo
135+
echo "### Full Changelog"
136+
echo "- Compare: ${LAST_TAG}...${RELEASE_TAG}"
137+
} > "${NOTES_FILE}"
138+
139+
echo "notes_file=${NOTES_FILE}" >> "$GITHUB_OUTPUT"
140+
141+
- name: Create or update draft GitHub release
142+
uses: ncipollo/release-action@v1
143+
with:
144+
allowUpdates: true
145+
bodyFile: ${{ steps.notes.outputs.notes_file }}
146+
commit: master
147+
draft: true
148+
name: v${{ steps.resolve.outputs.release_version }}
149+
tag: v${{ steps.resolve.outputs.release_version }}
150+
token: ${{ secrets.GITHUB_TOKEN }}
151+
152+
- name: Commit release prep
153+
run: |
154+
set -euo pipefail
155+
BRANCH="prepare-release-${{ steps.resolve.outputs.release_version }}"
156+
RELEASE_VERSION="${{ steps.resolve.outputs.release_version }}"
157+
SWAGGER_CODEGEN_VERSION="${{ steps.resolve.outputs.swagger_codegen_version }}"
158+
git config user.name "github-actions[bot]"
159+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
160+
git fetch origin "${BRANCH}" || true
161+
if git show-ref --verify --quiet "refs/remotes/origin/${BRANCH}"; then
162+
git checkout -B "${BRANCH}" "origin/${BRANCH}"
163+
git reset --hard "${GITHUB_SHA}"
164+
else
165+
git checkout -B "${BRANCH}"
166+
fi
167+
mvn -q -B versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false
168+
if [ -n "${SWAGGER_CODEGEN_VERSION}" ]; then
169+
mvn -q -B versions:set-property -Dproperty=swagger-codegen-version -DnewVersion="${SWAGGER_CODEGEN_VERSION}" -DgenerateBackupPoms=false
170+
fi
171+
git add pom.xml
172+
if git diff --cached --quiet; then
173+
echo "No pom.xml changes to commit."
174+
else
175+
git commit -m "chore: prepare release ${RELEASE_VERSION}"
176+
fi
177+
git push --force-with-lease origin "${BRANCH}"
178+
179+
- name: Create or update pull request
180+
env:
181+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
182+
run: |
183+
set -euo pipefail
184+
BRANCH="prepare-release-${{ steps.resolve.outputs.release_version }}"
185+
TITLE="chore: prepare release ${{ steps.resolve.outputs.release_version }}"
186+
BODY="Prepare release ${{ steps.resolve.outputs.release_version }} and draft notes."
187+
EXISTING="$(gh pr list --base master --head "${BRANCH}" --state open --json number --jq '.[0].number' || true)"
188+
if [ -n "${EXISTING}" ]; then
189+
echo "PR #${EXISTING} already exists; updating title and body."
190+
gh pr edit "${EXISTING}" --title "${TITLE}" --body "${BODY}"
191+
else
192+
gh pr create --base master --head "${BRANCH}" --title "${TITLE}" --body "${BODY}"
193+
fi

0 commit comments

Comments
 (0)