1- name : GitHub Actions Demo
1+ name : Release
22run-name : New Release Workflow
3+
34on :
45 workflow_dispatch :
5- inputs :
6- version :
7- description : ' Version number for the new release'
8- required : true
9- default : ' 2.0.0'
10- commit_hash :
11- description : ' Commit hash for the release'
12- required : true
13- default : ' '
14- message :
15- description : ' Release message'
16- required : true
17- default : ' '
6+
7+ permissions :
8+ contents : write
9+
1810jobs :
19- run-test :
11+ resolve-version :
12+ runs-on : ubuntu-latest
13+ outputs :
14+ version : ${{ steps.resolve.outputs.version }}
15+ tag : ${{ steps.resolve.outputs.tag }}
16+
17+ steps :
18+ - name : Checkout main with full history
19+ uses : actions/checkout@v4
20+ with :
21+ ref : main
22+ fetch-depth : 0
23+
24+ - name : Setup Java
25+ uses : actions/setup-java@v5
26+ with :
27+ distribution : temurin
28+ java-version : 21
29+ cache : maven
30+
31+ - name : Resolve version from pom.xml
32+ id : resolve
33+ shell : bash
34+ run : |
35+ VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout | tail -n 1)
36+
37+ if [[ -z "$VERSION" ]]; then
38+ echo "Could not resolve version from pom.xml"
39+ exit 1
40+ fi
41+
42+ if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
43+ echo "Invalid Maven version: $VERSION"
44+ exit 1
45+ fi
46+
47+ TAG="v$VERSION"
48+
49+ echo "Resolved version: $VERSION"
50+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
51+ echo "tag=$TAG" >> "$GITHUB_OUTPUT"
52+
53+ - name : Check that tag does not already exist
54+ shell : bash
55+ run : |
56+ TAG="${{ steps.resolve.outputs.tag }}"
57+
58+ if git ls-remote --tags origin "refs/tags/$TAG" | grep -q "$TAG"; then
59+ echo "Tag $TAG already exists"
60+ exit 1
61+ fi
62+
63+ - name : Check that CHANGELOG entry exists
64+ shell : bash
65+ run : |
66+ VERSION="${{ steps.resolve.outputs.version }}"
67+
68+ if ! grep -q "^## \[$VERSION\]" CHANGELOG.md; then
69+ echo "CHANGELOG.md does not contain section for version $VERSION"
70+ exit 1
71+ fi
72+
73+ build :
74+ runs-on : ubuntu-latest
75+ needs : resolve-version
76+
77+ steps :
78+ - name : Checkout main
79+ uses : actions/checkout@v4
80+ with :
81+ ref : main
82+
83+ - name : Setup Java
84+ uses : actions/setup-java@v5
85+ with :
86+ distribution : temurin
87+ java-version : 21
88+ cache : maven
89+
90+ - name : Show build info
91+ run : |
92+ echo "Building version ${{ needs.resolve-version.outputs.version }}"
93+ git log -1 --oneline
94+
95+ - name : Build Maven project
96+ run : mvn -B clean verify
97+
98+ create-tag :
2099 runs-on : ubuntu-latest
100+ needs : [resolve-version, build]
101+
21102 steps :
22- - name : Checkout code
103+ - name : Checkout main with full history
23104 uses : actions/checkout@v4
24105 with :
25- ref : ${{ github.event.inputs.commit_hash || github.sha }}
106+ ref : main
107+ fetch-depth : 0
26108
27- - name : Run Tests
28- run : mvn test
109+ - name : Configure git user
110+ run : |
111+ git config user.name "github-actions[bot]"
112+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
113+
114+ - name : Create tag on latest main commit
115+ shell : bash
116+ run : |
117+ TAG="${{ needs.resolve-version.outputs.tag }}"
118+ COMMIT_SHA=$(git rev-parse origin/main)
29119
120+ git tag -a "$TAG" "$COMMIT_SHA" -m "Release $TAG"
121+ git push origin "$TAG"
30122
31- - run : echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
32- - run : echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
33- - run : echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
34- - name : Check out repository code
123+ create-release :
124+ runs-on : ubuntu-latest
125+ needs : [resolve-version, create-tag]
126+
127+ steps :
128+ - name : Checkout repository
35129 uses : actions/checkout@v4
36- - run : echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
37- - run : echo "🖥️ The workflow is now ready to test your code on the runner."
38- - name : List files in the repository
130+ with :
131+ ref : main
132+ fetch-depth : 0
133+
134+ - name : Extract release notes from CHANGELOG.md
135+ shell : bash
136+ run : |
137+ VERSION="${{ needs.resolve-version.outputs.version }}"
138+ TAG="${{ needs.resolve-version.outputs.tag }}"
139+
140+ awk -v version="$VERSION" '
141+ $0 ~ "^## \\[" version "\\]" { capture=1; next }
142+ capture && $0 ~ "^## \\[" { exit }
143+ capture { print }
144+ ' CHANGELOG.md > RELEASE_BODY.md
145+
146+ if [ ! -s RELEASE_BODY.md ]; then
147+ echo "Could not find changelog entry for version $VERSION in CHANGELOG.md"
148+ exit 1
149+ fi
150+
151+ PREV_TAG=$(git tag --sort=-version:refname | grep '^v' | grep -vx "$TAG" | head -n 1 || true)
152+
153+ {
154+ echo "# Release $TAG"
155+ echo
156+ cat RELEASE_BODY.md
157+ echo
158+ if [ -n "$PREV_TAG" ]; then
159+ echo "Full Changelog: https://github.com/${{ github.repository }}/compare/$PREV_TAG...$TAG"
160+ fi
161+ } > RELEASE_NOTES.md
162+
163+ - name : Create GitHub release
164+ env :
165+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
39166 run : |
40- ls ${{ github.workspace }}
41- - run : echo "🍏 This job's status is ${{ job.status }}."
167+ TAG="${{ needs.resolve-version.outputs.tag }}"
168+
169+ gh release create "$TAG" \
170+ --title "Release $TAG" \
171+ --notes-file RELEASE_NOTES.md
0 commit comments