Skip to content

Commit dfbf7b3

Browse files
ejsmithclaude
andcommitted
Version and publish from git tags in one Build workflow
Match the other Exceptionless builds: MinVer computes the version from v* tags and every job builds with it (-Drevision). A v* tag publishes that version to Maven Central after the tests, end-to-end tests and the Spring Boot 4 job pass; other pushes publish a preview build to GitHub Packages; pull requests only build and test. release.yml is folded into build.yml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 564255f commit dfbf7b3

3 files changed

Lines changed: 167 additions & 63 deletions

File tree

‎.github/workflows/build.yml‎

Lines changed: 155 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
name: Build
22

3+
# Versions come from git tags (MinVer), like the other Exceptionless builds:
4+
# - A v* tag (v2.0.0, v2.1.0-beta.1) builds that version and publishes it to Maven Central.
5+
# - Other pushes build a pre-release version, such as 2.0.1-preview.0.12 on main or
6+
# 2.0.1-preview.my-branch.0.12 on a branch, and publish it to GitHub Packages.
7+
# - Pull requests build and test only.
8+
#
9+
# Required secrets for releases: CENTRAL_USERNAME and CENTRAL_PASSWORD (a Central Portal user
10+
# token), GPG_PRIVATE_KEY and GPG_PASSPHRASE.
311
on:
412
push:
5-
branches: [main]
613
pull_request:
714
workflow_dispatch:
815

@@ -11,11 +18,61 @@ permissions:
1118

1219
concurrency:
1320
group: ${{ github.workflow }}-${{ github.ref }}
14-
cancel-in-progress: true
21+
# Never cancel a tag build; it may be publishing a release.
22+
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }}
23+
24+
defaults:
25+
run:
26+
shell: bash
27+
28+
env:
29+
MAVEN_ARGS: --batch-mode --no-transfer-progress
1530

1631
jobs:
32+
version:
33+
name: Version
34+
runs-on: ubuntu-latest
35+
timeout-minutes: 10
36+
outputs:
37+
version: ${{ steps.version.outputs.version }}
38+
steps:
39+
- name: Checkout
40+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
41+
with:
42+
fetch-depth: 0
43+
44+
- name: Set up .NET for MinVer
45+
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
46+
with:
47+
dotnet-version: 10.0.x
48+
49+
- name: Compute version
50+
id: version
51+
run: |
52+
# Pre-release versions from branches other than main, maintenance branches (2.x, 2.1),
53+
# tags and pull requests carry the branch name.
54+
branch="${GITHUB_REF##*/}"
55+
if [[ "$GITHUB_REF" != refs/heads/* || "$branch" == main || "$branch" =~ ^[0-9]+\.(x|[0-9]+)$ ]]; then
56+
branch=""
57+
fi
58+
branch="$(tr -c 'A-Za-z0-9-' '-' <<< "$branch" | sed -E 's/-+$//')"
59+
suffix="${branch:+$branch.}"
60+
61+
dotnet tool install --global minver-cli --version 8.0.0
62+
version="$(minver --tag-prefix v --default-pre-release-identifiers "preview.${suffix}0" --minimum-major-minor 2.0)"
63+
64+
# After a pre-release tag (v2.1.0-beta.1) MinVer appends only the height; add the branch.
65+
if [[ -n "$branch" && "$version" != *"$branch"* ]]; then
66+
version="$(sed -E "s/\.([0-9]+)$/.${suffix}\1/" <<< "$version")"
67+
fi
68+
69+
echo "version=$version" >> "$GITHUB_OUTPUT"
70+
echo "### Version: $version" >> "$GITHUB_STEP_SUMMARY"
71+
echo "Version: $version (ref: $GITHUB_REF, event: $GITHUB_EVENT_NAME)"
72+
1773
build:
1874
name: JDK ${{ matrix.java }} on ${{ matrix.os }}
75+
needs: version
1976
runs-on: ${{ matrix.os }}
2077
timeout-minutes: 30
2178
strategy:
@@ -40,7 +97,9 @@ jobs:
4097
cache: maven
4198

4299
- name: Build and test
43-
run: ./mvnw -B -ntp verify
100+
run: ./mvnw verify -Drevision="$VERSION"
101+
env:
102+
VERSION: ${{ needs.version.outputs.version }}
44103

45104
- name: Upload test reports
46105
if: failure()
@@ -51,29 +110,116 @@ jobs:
51110

52111
spring-boot-4:
53112
name: Spring Boot 4 compatibility
113+
needs: version
54114
runs-on: ubuntu-latest
55115
timeout-minutes: 30
56116
steps:
57-
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
58-
- uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
117+
- name: Checkout
118+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
119+
120+
- name: Set up JDK
121+
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
59122
with:
60123
distribution: temurin
61124
java-version: 21
62125
cache: maven
126+
63127
- name: Test the starter against Spring Boot 4
64-
run: ./mvnw -B -ntp -pl exceptionless-spring-boot-starter -am verify -Pspring-boot-4
128+
run: ./mvnw -pl exceptionless-spring-boot-starter -am verify -Pspring-boot-4 -Drevision="$VERSION"
129+
env:
130+
VERSION: ${{ needs.version.outputs.version }}
65131

66132
e2e:
67133
name: End-to-end (real Exceptionless server)
134+
needs: version
68135
runs-on: ubuntu-latest
69136
timeout-minutes: 45
137+
# Every push (so every published build) and pull requests labeled e2e.
70138
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'e2e')
71139
steps:
72-
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
73-
- uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
140+
- name: Checkout
141+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
142+
143+
- name: Set up JDK
144+
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
74145
with:
75146
distribution: temurin
76147
java-version: 21
77148
cache: maven
149+
78150
- name: Run end-to-end tests
79-
run: ./mvnw -B -ntp -pl exceptionless-e2e-tests -am verify -De2e=true
151+
run: ./mvnw -pl exceptionless-e2e-tests -am verify -De2e=true -Drevision="$VERSION"
152+
env:
153+
VERSION: ${{ needs.version.outputs.version }}
154+
155+
publish-ci:
156+
name: Publish CI packages
157+
needs: [version, build, spring-boot-4, e2e]
158+
if: github.event_name != 'pull_request' && startsWith(github.ref, 'refs/heads/') && github.actor != 'dependabot[bot]'
159+
runs-on: ubuntu-latest
160+
timeout-minutes: 30
161+
permissions:
162+
contents: read
163+
packages: write
164+
steps:
165+
- name: Checkout
166+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
167+
168+
- name: Set up JDK
169+
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
170+
with:
171+
distribution: temurin
172+
java-version: 21
173+
cache: maven
174+
server-id: github
175+
server-username: GITHUB_ACTOR
176+
server-password: GITHUB_TOKEN
177+
178+
- name: Publish to GitHub Packages
179+
# A CI package is a convenience; failing to publish one doesn't fail the build.
180+
continue-on-error: true
181+
run: >-
182+
./mvnw deploy -DskipTests -Drevision="$VERSION"
183+
-DaltDeploymentRepository="github::https://maven.pkg.github.com/$GITHUB_REPOSITORY"
184+
env:
185+
VERSION: ${{ needs.version.outputs.version }}
186+
GITHUB_TOKEN: ${{ github.token }}
187+
188+
release:
189+
name: Publish to Maven Central
190+
needs: [version, build, spring-boot-4, e2e]
191+
if: startsWith(github.ref, 'refs/tags/v')
192+
runs-on: ubuntu-latest
193+
timeout-minutes: 60
194+
steps:
195+
- name: Check the version matches the tag
196+
run: |
197+
if [[ "$VERSION" != "${GITHUB_REF_NAME#v}" ]]; then
198+
echo "::error::Tag $GITHUB_REF_NAME is not a version tag (computed version: $VERSION)."
199+
exit 1
200+
fi
201+
env:
202+
VERSION: ${{ needs.version.outputs.version }}
203+
204+
- name: Checkout
205+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
206+
207+
- name: Set up JDK
208+
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
209+
with:
210+
distribution: temurin
211+
java-version: 21
212+
cache: maven
213+
server-id: central
214+
server-username: CENTRAL_USERNAME
215+
server-password: CENTRAL_PASSWORD
216+
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
217+
gpg-passphrase: GPG_PASSPHRASE
218+
219+
- name: Publish to Maven Central
220+
run: ./mvnw deploy -Prelease -DskipTests -Drevision="$VERSION"
221+
env:
222+
VERSION: ${{ needs.version.outputs.version }}
223+
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
224+
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
225+
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

‎.github/workflows/release.yml‎

Lines changed: 0 additions & 50 deletions
This file was deleted.

‎CONTRIBUTING.md‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,15 @@ Test helpers shared between modules (`FakeServer`, `TestClients`) live in
4444
(`Duration`, `InstantSource`) instead of numbers, immutable collections from getters, and plain
4545
JavaBeans (`void` setters) for the mutable models.
4646

47-
## Releasing
48-
49-
Push a tag like `v2.0.0`. The release workflow builds, signs and publishes every module to Maven Central
50-
and creates a GitHub release.
47+
## Versions and releases
48+
49+
Versions come from git tags through [MinVer](https://github.com/adamralph/minver), the same as the
50+
other Exceptionless builds. Local builds are `2.0.0-SNAPSHOT`; CI passes the computed version as
51+
`-Drevision`.
52+
53+
- To release, push a tag such as `v2.0.0` or `v2.1.0-beta.1`, or create a GitHub release with one. The
54+
Build workflow tests that commit and publishes every module to Maven Central under the tag's version.
55+
- Every other push publishes a pre-release build to GitHub Packages, versioned from the latest tag:
56+
`2.0.1-preview.0.12` on `main`, `2.0.1-preview.my-branch.0.12` on a branch.
57+
- Pull requests build and test only. Add the `e2e` label to also run the end-to-end tests; pushes
58+
always run them.

0 commit comments

Comments
 (0)