Release #31
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
| # .github/workflows/release.yml | |
| name: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: "DRY RUN: Do not push/tag or create a GitHub Release" | |
| type: boolean | |
| default: false | |
| base_ref: | |
| description: "Branch to release from (for testing)" | |
| type: string | |
| default: "main" | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: release-${{ github.event.inputs.base_ref || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| prepare-release: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag_name: ${{ steps.set_tag.outputs.tag_name }} | |
| dsl_version: ${{ steps.get_dsl_version.outputs.dsl_version }} | |
| artifact_id: ${{ steps.get_artifact_id.outputs.artifact_id }} | |
| steps: | |
| - name: Checkout base branch | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.inputs.base_ref || 'main' }} | |
| persist-credentials: true | |
| - name: Set up Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: 21 | |
| cache: maven | |
| - name: Get DSL version from pom.xml | |
| id: get_dsl_version | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| DSL_VERSION=$(mvn -q help:evaluate -Dexpression=rosetta.dsl.version -DforceStdout) | |
| if [ -z "${DSL_VERSION:-}" ]; then | |
| echo "Failed to resolve rosetta.dsl.version from pom.xml" | |
| exit 1 | |
| fi | |
| echo "dsl_version=$DSL_VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Get artifactId from pom.xml | |
| id: get_artifact_id | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ARTIFACT_ID=$(mvn -q help:evaluate -Dexpression=project.artifactId -DforceStdout) | |
| if [ -z "${ARTIFACT_ID:-}" ]; then | |
| echo "Failed to resolve project.artifactId from pom.xml" | |
| exit 1 | |
| fi | |
| echo "artifact_id=$ARTIFACT_ID" >> "$GITHUB_OUTPUT" | |
| - name: Ensure up-to-date and fetch tags | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| git config --global pull.ff only | |
| git fetch --prune --tags origin | |
| git pull --ff-only origin "${{ github.event.inputs.base_ref || 'main' }}" | |
| - name: Determine next tag | |
| id: set_tag | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| DSL_VERSION="${{ steps.get_dsl_version.outputs.dsl_version }}" | |
| DSL_ESCAPED=$(printf '%s\n' "$DSL_VERSION" | sed -e 's/[]\/$*.^|[]/\\&/g') | |
| EXISTING=$(git tag -l "${DSL_VERSION}.*" | grep -E "^${DSL_ESCAPED}\.[0-9]+$" || true) | |
| if [ -z "$EXISTING" ]; then | |
| NEXT_TAG="${DSL_VERSION}.0" | |
| else | |
| MAX_N=$(echo "$EXISTING" | sed -E "s/^${DSL_ESCAPED}\.//" | sort -n | tail -1) | |
| NEXT_TAG="${DSL_VERSION}.$((MAX_N + 1))" | |
| fi | |
| echo "Next tag computed: $NEXT_TAG" | |
| echo "tag_name=$NEXT_TAG" >> "$GITHUB_OUTPUT" | |
| - name: Guard only allow real release from main | |
| if: ${{ github.event.inputs.dry_run != 'true' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.event.inputs.base_ref || 'main' }}" != "main" ]; then | |
| echo "Unable to perform a release from '${{ github.event.inputs.base_ref }}'. Use main or set dry_run=true." | |
| exit 1 | |
| fi | |
| - name: Bump version, tag, and push (skipped in dry run) | |
| env: | |
| TAG_NAME: ${{ steps.set_tag.outputs.tag_name }} | |
| DRY_RUN: ${{ github.event.inputs.dry_run }} | |
| BASE_REF: ${{ github.event.inputs.base_ref || 'main' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [ "${DRY_RUN}" = "true" ]; then | |
| echo "[DRY RUN] Would set project version to ${TAG_NAME}, commit, tag, and push atomically to ${BASE_REF}." | |
| exit 0 | |
| fi | |
| # We skip committing changes to the repo. Use versions:set only in the build step ephemerally. | |
| echo "Skipping persistent version bump in pom.xml to avoid branch protection issues." | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| git config --global user.name "github-actions[bot]" | |
| git fetch --prune --tags origin | |
| if git rev-parse "${TAG_NAME}" >/dev/null 2>&1; then | |
| echo "Tag ${TAG_NAME} already exists. Exiting." | |
| exit 1 | |
| fi | |
| git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME}" | |
| git push --atomic origin HEAD:"${BASE_REF}" "${TAG_NAME}" | |
| build-and-verify-release: | |
| needs: prepare-release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout the tag (real release) | |
| if: ${{ github.event.inputs.dry_run != 'true' }} | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ needs.prepare-release.outputs.tag_name }} | |
| - name: Checkout the base branch (dry run) | |
| if: ${{ github.event.inputs.dry_run == 'true' }} | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.inputs.base_ref || 'main' }} | |
| - name: Set up Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: 21 | |
| cache: maven | |
| - name: Set project version for build (ephemeral) | |
| env: | |
| TAG_NAME: ${{ needs.prepare-release.outputs.tag_name }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mvn -q -B versions:set -DnewVersion="${TAG_NAME}" -DgenerateBackupPoms=false | |
| - name: Build JARs | |
| shell: bash | |
| run: mvn -B clean package | |
| - name: Collect artifact paths | |
| id: archive | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ARTIFACT_ID="${{ needs.prepare-release.outputs.artifact_id }}" | |
| TAG_NAME="${{ needs.prepare-release.outputs.tag_name }}" | |
| JAR="target/${ARTIFACT_ID}-${TAG_NAME}.jar" | |
| JDOC="target/${ARTIFACT_ID}-${TAG_NAME}-javadoc.jar" | |
| if [ ! -f "$JAR" ]; then echo "Missing $JAR"; ls -l target || true; exit 1; fi | |
| if [ ! -f "$JDOC" ]; then echo "Missing $JDOC"; ls -l target || true; exit 1; fi | |
| echo "jar_path=$JAR" >> "$GITHUB_OUTPUT" | |
| echo "javadoc_jar_path=$JDOC" >> "$GITHUB_OUTPUT" | |
| - name: In dry run - upload build outputs as workflow artifacts | |
| if: ${{ github.event.inputs.dry_run == 'true' }} | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: dry-run-${{ needs.prepare-release.outputs.tag_name }} | |
| path: | | |
| ${{ steps.archive.outputs.jar_path }} | |
| ${{ steps.archive.outputs.javadoc_jar_path }} | |
| retention-days: 3 | |
| - name: Create GitHub Release (real release) | |
| if: ${{ github.event.inputs.dry_run != 'true' }} | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.prepare-release.outputs.tag_name }} | |
| name: ${{ needs.prepare-release.outputs.tag_name }} | |
| body: | | |
| Automated release for DSL version ${{ needs.prepare-release.outputs.dsl_version }} | |
| files: | | |
| ${{ steps.archive.outputs.jar_path }} | |
| ${{ steps.archive.outputs.javadoc_jar_path }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |