Skip to content

Commit 1fe68e3

Browse files
prep for dry runs of release testing
1 parent 7849228 commit 1fe68e3

File tree

1 file changed

+106
-47
lines changed

1 file changed

+106
-47
lines changed

.github/workflows/release.yml

Lines changed: 106 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,37 @@ name: Release
22

33
on:
44
workflow_dispatch:
5+
inputs:
6+
dry_run:
7+
description: "Do not push/tag or create a GitHub Release"
8+
type: boolean
9+
default: true
10+
base_ref:
11+
description: "Branch to release from (for testing)"
12+
type: string
13+
default: "main"
14+
15+
permissions:
16+
contents: write
517

618
concurrency:
7-
group: release-${{ github.ref }}
19+
group: release-${{ github.event.inputs.base_ref || github.ref }}
820
cancel-in-progress: true
921

1022
jobs:
11-
tag:
23+
prepare-release:
1224
runs-on: ubuntu-latest
1325
outputs:
1426
tag_name: ${{ steps.set_tag.outputs.tag_name }}
1527
dsl_version: ${{ steps.get_dsl_version.outputs.dsl_version }}
1628
artifact_id: ${{ steps.get_artifact_id.outputs.artifact_id }}
1729
steps:
18-
- name: Checkout code
30+
- name: Checkout base branch
1931
uses: actions/checkout@v5
2032
with:
2133
fetch-depth: 0
34+
ref: ${{ github.event.inputs.base_ref || 'main' }}
35+
persist-credentials: true
2236

2337
- name: Set up Java
2438
uses: actions/setup-java@v5
@@ -29,55 +43,106 @@ jobs:
2943

3044
- name: Get DSL version from pom.xml
3145
id: get_dsl_version
46+
shell: bash
3247
run: |
33-
DSL_VERSION=$(mvn help:evaluate -Dexpression=rosetta.dsl.version -q -DforceStdout)
34-
echo "dsl_version=$DSL_VERSION" >> $GITHUB_OUTPUT
48+
set -euo pipefail
49+
DSL_VERSION=$(mvn -q help:evaluate -Dexpression=rosetta.dsl.version -DforceStdout)
50+
if [ -z "${DSL_VERSION:-}" ]; then
51+
echo "Failed to resolve rosetta.dsl.version from pom.xml"
52+
exit 1
53+
fi
54+
echo "dsl_version=$DSL_VERSION" >> "$GITHUB_OUTPUT"
3555
3656
- name: Get artifactId from pom.xml
3757
id: get_artifact_id
58+
shell: bash
3859
run: |
39-
ARTIFACT_ID=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout)
40-
echo "artifact_id=$ARTIFACT_ID" >> $GITHUB_OUTPUT
60+
set -euo pipefail
61+
ARTIFACT_ID=$(mvn -q help:evaluate -Dexpression=project.artifactId -DforceStdout)
62+
if [ -z "${ARTIFACT_ID:-}" ]; then
63+
echo "Failed to resolve project.artifactId from pom.xml"
64+
exit 1
65+
fi
66+
echo "artifact_id=$ARTIFACT_ID" >> "$GITHUB_OUTPUT"
4167
42-
- name: Fetch all tags
43-
run: git fetch --tags
68+
- name: Ensure up-to-date and fetch tags
69+
shell: bash
70+
run: |
71+
set -euo pipefail
72+
git config --global pull.ff only
73+
git fetch --prune --tags origin
74+
git pull --ff-only origin "${{ github.event.inputs.base_ref || 'main' }}"
4475
4576
- name: Determine next tag
4677
id: set_tag
78+
shell: bash
4779
run: |
80+
set -euo pipefail
4881
DSL_VERSION="${{ steps.get_dsl_version.outputs.dsl_version }}"
49-
TAGS=$(git tag --list "${DSL_VERSION}.*" | sort -V)
50-
if [ -z "$TAGS" ]; then
82+
DSL_ESCAPED=$(printf '%s\n' "$DSL_VERSION" | sed -e 's/[]\/$*.^|[]/\\&/g')
83+
84+
EXISTING=$(git tag -l "${DSL_VERSION}.*" | grep -E "^${DSL_ESCAPED}\.[0-9]+$" || true)
85+
if [ -z "$EXISTING" ]; then
5186
NEXT_TAG="${DSL_VERSION}.0"
5287
else
53-
MAX_N=$(echo "$TAGS" | sed "s/^${DSL_VERSION}\.//" | sort -n | tail -1)
54-
NEXT_N=$((MAX_N + 1))
55-
NEXT_TAG="${DSL_VERSION}.${NEXT_N}"
88+
MAX_N=$(echo "$EXISTING" | sed -E "s/^${DSL_ESCAPED}\.//" | sort -n | tail -1)
89+
NEXT_TAG="${DSL_VERSION}.$((MAX_N + 1))"
5690
fi
57-
echo "tag_name=$NEXT_TAG" >> $GITHUB_OUTPUT
91+
echo "Next tag computed: $NEXT_TAG"
92+
echo "tag_name=$NEXT_TAG" >> "$GITHUB_OUTPUT"
5893
59-
- name: Create and push tag
94+
- name: Guard: only allow real release from main
95+
if: ${{ github.event.inputs.dry_run != 'true' }}
96+
shell: bash
97+
run: |
98+
set -euo pipefail
99+
if [ "${{ github.event.inputs.base_ref || 'main' }}" != "main" ]; then
100+
echo "Refusing to perform a real release from '${{ github.event.inputs.base_ref }}'. Use main or set dry_run=true."
101+
exit 1
102+
fi
103+
104+
- name: Bump version, tag, and push (skipped in dry run)
60105
env:
61-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106+
TAG_NAME: ${{ steps.set_tag.outputs.tag_name }}
107+
DRY_RUN: ${{ github.event.inputs.dry_run }}
108+
BASE_REF: ${{ github.event.inputs.base_ref || 'main' }}
109+
shell: bash
62110
run: |
63-
TAG_NAME="${{ steps.set_tag.outputs.tag_name }}"
64-
if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
65-
echo "Tag $TAG_NAME already exists. Exiting."
111+
set -euo pipefail
112+
if [ "${DRY_RUN}" = "true" ]; then
113+
echo "[DRY RUN] Would set project version to ${TAG_NAME}, commit, tag, and push atomically to ${BASE_REF}."
114+
exit 0
115+
fi
116+
117+
mvn -q -B versions:set -DnewVersion="${TAG_NAME}" -DgenerateBackupPoms=false
118+
if ! git diff --quiet; then
119+
git config user.name "github-actions[bot]"
120+
git config user.email "github-actions[bot]@users.noreply.github.com"
121+
git add -A
122+
git commit -m "Release ${TAG_NAME}: set project version to ${TAG_NAME}"
123+
else
124+
echo "No changes to commit (version already ${TAG_NAME})."
125+
fi
126+
127+
git fetch --prune --tags origin
128+
if git rev-parse "${TAG_NAME}" >/dev/null 2>&1; then
129+
echo "Tag ${TAG_NAME} already exists. Exiting."
66130
exit 1
67131
fi
68-
git config user.name "github-actions[bot]"
69-
git config user.email "github-actions[bot]@users.noreply.github.com"
70-
git tag "$TAG_NAME"
71-
git push origin "$TAG_NAME"
132+
133+
git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME}"
134+
git push --atomic origin HEAD:"${BASE_REF}" "${TAG_NAME}"
72135
73136
build-and-release:
74-
needs: tag
137+
needs: prepare-release
138+
if: ${{ github.event.inputs.dry_run != 'true' }}
75139
runs-on: ubuntu-latest
76140
steps:
77-
- name: Checkout code
141+
- name: Checkout the tag (build exactly what was released)
78142
uses: actions/checkout@v5
79143
with:
80144
fetch-depth: 0
145+
ref: ${{ needs.prepare-release.outputs.tag_name }}
81146

82147
- name: Set up Java
83148
uses: actions/setup-java@v5
@@ -86,39 +151,33 @@ jobs:
86151
java-version: 21
87152
cache: maven
88153

89-
- name: Save original pom.xml
90-
run: cp pom.xml pom.xml.bak
91-
92-
- name: Update pom.xml version to match tag
93-
run: |
94-
mvn -B versions:set -DnewVersion=${{ needs.tag.outputs.tag_name }}
95-
mvn -B versions:commit
96-
97154
- name: Build JARs
155+
shell: bash
98156
run: mvn -B clean package
99157

100-
- name: Revert pom.xml to original
101-
run: mv pom.xml.bak pom.xml
102-
103-
- name: Archive JARs
158+
- name: Collect artifact paths
104159
id: archive
160+
shell: bash
105161
run: |
106-
ARTIFACT_ID="${{ needs.tag.outputs.artifact_id }}"
107-
TAG_NAME="${{ needs.tag.outputs.tag_name }}"
162+
set -euo pipefail
163+
ARTIFACT_ID="${{ needs.prepare-release.outputs.artifact_id }}"
164+
TAG_NAME="${{ needs.prepare-release.outputs.tag_name }}"
108165
JAR="target/${ARTIFACT_ID}-${TAG_NAME}.jar"
109-
JAVADOC_JAR="target/${ARTIFACT_ID}-${TAG_NAME}-javadoc.jar"
110-
echo "jar_path=$JAR" >> $GITHUB_OUTPUT
111-
echo "javadoc_jar_path=$JAVADOC_JAR" >> $GITHUB_OUTPUT
166+
JDOC="target/${ARTIFACT_ID}-${TAG_NAME}-javadoc.jar"
167+
if [ ! -f "$JAR" ]; then echo "Missing $JAR"; exit 1; fi
168+
if [ ! -f "$JDOC" ]; then echo "Missing $JDOC"; exit 1; fi
169+
echo "jar_path=$JAR" >> "$GITHUB_OUTPUT"
170+
echo "javadoc_jar_path=$JDOC" >> "$GITHUB_OUTPUT"
112171
113172
- name: Create GitHub Release
114173
uses: softprops/action-gh-release@v2
115174
with:
116-
tag_name: ${{ needs.tag.outputs.tag_name }}
117-
name: ${{ needs.tag.outputs.tag_name }}
175+
tag_name: ${{ needs.prepare-release.outputs.tag_name }}
176+
name: ${{ needs.prepare-release.outputs.tag_name }}
118177
body: |
119-
Automated release for DSL version ${{ needs.tag.outputs.dsl_version }}
178+
Automated release for DSL version ${{ needs.prepare-release.outputs.dsl_version }}
120179
files: |
121180
${{ steps.archive.outputs.jar_path }}
122181
${{ steps.archive.outputs.javadoc_jar_path }}
123182
env:
124-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
183+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)