Prepare Release #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Prepare Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_version: | |
| description: "Release version (format: 1.X.Y)" | |
| required: false | |
| default: "" | |
| type: string | |
| swagger_codegen_version: | |
| description: "swagger-codegen release version to pin (e.g. 3.0.79)" | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| prepare: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: master | |
| fetch-depth: 0 | |
| - name: Set up Java 11 | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: "11" | |
| distribution: temurin | |
| cache: maven | |
| overwrite-settings: false | |
| - name: Add Central-Portal snapshot repo to settings.xml | |
| uses: s4u/maven-settings-action@v4.0.0 | |
| with: | |
| repositories: '[{"id":"central-portal-snapshots","name":"Sonatype Central Portal snapshots","url":"https://central.sonatype.com/repository/maven-snapshots/","releases":{"enabled":false},"snapshots":{"enabled":true}}]' | |
| servers: '[{"id":"central","username":"${{ secrets.MAVEN_CENTRAL_USERNAME }}","password":"${{ secrets.MAVEN_CENTRAL_PASSWORD }}"}]' | |
| - name: Resolve and validate inputs | |
| id: resolve | |
| run: | | |
| set -euo pipefail | |
| POM_VERSION="$(mvn -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec)" | |
| POM_RELEASE_VERSION="${POM_VERSION%-SNAPSHOT}" | |
| RELEASE_VERSION="${{ inputs.release_version }}" | |
| if [ -z "${RELEASE_VERSION}" ]; then | |
| RELEASE_VERSION="${POM_RELEASE_VERSION}" | |
| fi | |
| if [[ ! "$RELEASE_VERSION" =~ ^1\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "release_version must match 1.X.Y" | |
| exit 1 | |
| fi | |
| SWAGGER_CODEGEN_VERSION="${{ inputs.swagger_codegen_version }}" | |
| if [[ "$SWAGGER_CODEGEN_VERSION" =~ SNAPSHOT$ ]]; then | |
| echo "Release dependency versions must not be SNAPSHOT: $SWAGGER_CODEGEN_VERSION" | |
| exit 1 | |
| fi | |
| echo "release_version=${RELEASE_VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "swagger_codegen_version=${SWAGGER_CODEGEN_VERSION}" >> "$GITHUB_OUTPUT" | |
| - name: Update versions | |
| run: | | |
| set -euo pipefail | |
| RELEASE_VERSION="${{ steps.resolve.outputs.release_version }}" | |
| SWAGGER_CODEGEN_VERSION="${{ steps.resolve.outputs.swagger_codegen_version }}" | |
| mvn -q -B versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false | |
| if [ -n "${SWAGGER_CODEGEN_VERSION}" ]; then | |
| mvn -q -B versions:set-property -Dproperty=swagger-codegen-version -DnewVersion="${SWAGGER_CODEGEN_VERSION}" -DgenerateBackupPoms=false | |
| fi | |
| - name: Build release candidate | |
| run: | | |
| set -euo pipefail | |
| CODEGEN_VERSION="${{ steps.resolve.outputs.swagger_codegen_version }}" | |
| CODEGEN_MAJOR="${CODEGEN_VERSION%%.*}" | |
| CODEGEN_VERSION_PROPERTY="" | |
| 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")" | |
| CODEGEN_FOUND="$(echo "${CODEGEN_FOUND_JSON}" | jq '.response.numFound')" | |
| if [[ "${CODEGEN_FOUND}" == "0" ]]; then | |
| SNAP_API="https://central.sonatype.com/repository/maven-snapshots" | |
| ARTIFACT_PATH="io/swagger/codegen/v3/swagger-codegen" | |
| ROOT_META="${SNAP_API}/${ARTIFACT_PATH}/maven-metadata.xml" | |
| LAST_SNAP="$(curl -s "$ROOT_META" | grep -oP "(?<=<version>)${CODEGEN_MAJOR}\.[^<]+" | sort -V | tail -n1)" | |
| CODEGEN_VERSION_PROPERTY="-Dswagger-codegen-version=${LAST_SNAP}" | |
| fi | |
| ./mvnw clean verify -U ${CODEGEN_VERSION_PROPERTY} | |
| - name: Prepare draft release notes body | |
| id: notes | |
| run: | | |
| set -euo pipefail | |
| RELEASE_VERSION="${{ steps.resolve.outputs.release_version }}" | |
| LAST_TAG_VERSION="$( | |
| { | |
| git tag -l 'v1.*' | sed 's/^v//' | |
| echo "${RELEASE_VERSION}" | |
| } \ | |
| | grep -E '^1\.[0-9]+\.[0-9]+$' \ | |
| | sort -V \ | |
| | awk -v rel="${RELEASE_VERSION}" ' | |
| $0 == rel { print prev; found=1; exit } | |
| { prev=$0 } | |
| END { if (!found) exit 1 } | |
| ' | |
| )" | |
| if [ -z "${LAST_TAG_VERSION}" ]; then | |
| echo "No previous v1.* tag found before ${RELEASE_VERSION}" | |
| exit 1 | |
| fi | |
| LAST_TAG="v${LAST_TAG_VERSION}" | |
| RELEASE_TAG="v${{ steps.resolve.outputs.release_version }}" | |
| NOTES_FILE="${RUNNER_TEMP}/release-notes-${RELEASE_TAG}.md" | |
| { | |
| echo "## ${RELEASE_TAG}" | |
| echo | |
| echo "### Notable Changes" | |
| git log \ | |
| --first-parent \ | |
| --pretty='- %s (%h)' \ | |
| --invert-grep \ | |
| --grep='^chore: prepare release ' \ | |
| --grep='^chore: bump snapshot to ' \ | |
| "${LAST_TAG}..HEAD" | |
| echo | |
| echo "### Full Changelog" | |
| echo "- Compare: ${LAST_TAG}...${RELEASE_TAG}" | |
| } > "${NOTES_FILE}" | |
| echo "notes_file=${NOTES_FILE}" >> "$GITHUB_OUTPUT" | |
| - name: Create or update draft GitHub release | |
| uses: ncipollo/release-action@v1 | |
| with: | |
| allowUpdates: true | |
| bodyFile: ${{ steps.notes.outputs.notes_file }} | |
| commit: master | |
| draft: true | |
| name: v${{ steps.resolve.outputs.release_version }} | |
| tag: v${{ steps.resolve.outputs.release_version }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Commit release prep | |
| run: | | |
| set -euo pipefail | |
| BRANCH="prepare-release-${{ steps.resolve.outputs.release_version }}" | |
| RELEASE_VERSION="${{ steps.resolve.outputs.release_version }}" | |
| SWAGGER_CODEGEN_VERSION="${{ steps.resolve.outputs.swagger_codegen_version }}" | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git fetch origin "${BRANCH}" || true | |
| if git show-ref --verify --quiet "refs/remotes/origin/${BRANCH}"; then | |
| git checkout -B "${BRANCH}" "origin/${BRANCH}" | |
| git reset --hard "${GITHUB_SHA}" | |
| else | |
| git checkout -B "${BRANCH}" | |
| fi | |
| mvn -q -B versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false | |
| if [ -n "${SWAGGER_CODEGEN_VERSION}" ]; then | |
| mvn -q -B versions:set-property -Dproperty=swagger-codegen-version -DnewVersion="${SWAGGER_CODEGEN_VERSION}" -DgenerateBackupPoms=false | |
| fi | |
| git add pom.xml | |
| if git diff --cached --quiet; then | |
| echo "No pom.xml changes to commit." | |
| else | |
| git commit -m "chore: prepare release ${RELEASE_VERSION}" | |
| fi | |
| git push --force-with-lease origin "${BRANCH}" | |
| - name: Create or update pull request | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| BRANCH="prepare-release-${{ steps.resolve.outputs.release_version }}" | |
| TITLE="chore: prepare release ${{ steps.resolve.outputs.release_version }}" | |
| BODY="Prepare release ${{ steps.resolve.outputs.release_version }} and draft notes." | |
| EXISTING="$(gh pr list --base master --head "${BRANCH}" --state open --json number --jq '.[0].number' || true)" | |
| if [ -n "${EXISTING}" ]; then | |
| echo "PR #${EXISTING} already exists; updating title and body." | |
| gh pr edit "${EXISTING}" --title "${TITLE}" --body "${BODY}" | |
| else | |
| gh pr create --base master --head "${BRANCH}" --title "${TITLE}" --body "${BODY}" | |
| fi |