Skip to content

Commit 79c11b2

Browse files
Add automated release workflow and documentation
Co-authored-by: thomasturrell <1552612+thomasturrell@users.noreply.github.com>
1 parent c61a01b commit 79c11b2

4 files changed

Lines changed: 277 additions & 1 deletion

File tree

.github/workflows/maven-publish.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
# DEPRECATED: This workflow is kept for backward compatibility only
2+
#
3+
# Please use the automated release process instead:
4+
# 1. Create a new release in GitHub UI with tag format vX.Y.Z
5+
# 2. The "Automated Release" workflow will handle the rest
6+
#
17
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
28
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
39

4-
name: Maven Release
10+
name: Maven Release (Manual - Deprecated)
511

612
on: workflow_dispatch
713
jobs:

.github/workflows/release.yml

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# This workflow automates the release process when a release is created on GitHub
2+
# It creates a release branch, updates versions, and deploys to Maven Central
3+
#
4+
# Usage:
5+
# 1. Create a new release in GitHub UI with tag format: vX.Y.Z (e.g., v1.2.0)
6+
# 2. This workflow will automatically:
7+
# - Create a release-X.Y.Z branch
8+
# - Update pom.xml versions to release version
9+
# - Build and deploy artifacts to Maven Central
10+
# - Update pom.xml to next development version
11+
# - Push version commits back to the release branch
12+
13+
name: Automated Release
14+
15+
on:
16+
release:
17+
types: [created] # Trigger when release is created (before it's published)
18+
19+
permissions:
20+
contents: write # Required to create branches and push commits
21+
22+
jobs:
23+
release:
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- name: Validate release tag format
28+
id: validate_tag
29+
run: |
30+
TAG_NAME="${{ github.event.release.tag_name }}"
31+
echo "Release tag: $TAG_NAME"
32+
33+
# Validate tag format (should be vX.Y.Z)
34+
if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
35+
echo "::error::Invalid tag format. Expected format: vX.Y.Z (e.g., v1.2.0)"
36+
exit 1
37+
fi
38+
39+
# Remove 'v' prefix to get the version number
40+
VERSION="${TAG_NAME#v}"
41+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
42+
echo "Extracted version: $VERSION"
43+
44+
# Create release branch name
45+
RELEASE_BRANCH="release-${VERSION}"
46+
echo "release_branch=${RELEASE_BRANCH}" >> $GITHUB_OUTPUT
47+
echo "Release branch: $RELEASE_BRANCH"
48+
49+
# Calculate next development version (increment patch version)
50+
IFS='.' read -ra VERSION_PARTS <<< "$VERSION"
51+
MAJOR="${VERSION_PARTS[0]}"
52+
MINOR="${VERSION_PARTS[1]}"
53+
PATCH="${VERSION_PARTS[2]}"
54+
NEXT_PATCH=$((PATCH + 1))
55+
NEXT_VERSION="${MAJOR}.${MINOR}.${NEXT_PATCH}-SNAPSHOT"
56+
echo "next_version=${NEXT_VERSION}" >> $GITHUB_OUTPUT
57+
echo "Next development version: $NEXT_VERSION"
58+
59+
- name: Checkout repository at release tag
60+
uses: actions/checkout@v3
61+
with:
62+
ref: ${{ github.event.release.tag_name }}
63+
fetch-depth: 0
64+
token: ${{ secrets.GITHUB_TOKEN }}
65+
66+
- name: Create release branch
67+
run: |
68+
RELEASE_BRANCH="${{ steps.validate_tag.outputs.release_branch }}"
69+
70+
# Create new branch from the release tag
71+
git checkout -b "$RELEASE_BRANCH"
72+
echo "Created branch $RELEASE_BRANCH from tag ${{ github.event.release.tag_name }}"
73+
74+
- name: Set up JDK 17
75+
uses: actions/setup-java@v5
76+
with:
77+
java-version: "17"
78+
distribution: "temurin"
79+
cache: maven
80+
server-id: central
81+
server-username: MAVEN_USERNAME
82+
server-password: MAVEN_PASSWORD
83+
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
84+
gpg-passphrase: MAVEN_GPG_PASSPHRASE
85+
86+
- name: Configure Git
87+
run: |
88+
git config user.name "github-actions[bot]"
89+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
90+
91+
- name: Set release version in POM
92+
run: |
93+
VERSION="${{ steps.validate_tag.outputs.version }}"
94+
echo "Setting version to: $VERSION"
95+
96+
# Use Maven versions plugin to set the version
97+
./mvnw -B versions:set -DnewVersion="${VERSION}" -DgenerateBackupPoms=false
98+
99+
# Commit the version change
100+
git add .
101+
git commit -m "[maven-release-plugin] prepare release v${VERSION}"
102+
103+
- name: Build and deploy release
104+
run: |
105+
VERSION="${{ steps.validate_tag.outputs.version }}"
106+
echo "Building and deploying version: $VERSION"
107+
108+
# Build and deploy with release profile (includes signing, sources, javadocs)
109+
./mvnw -B clean deploy -Prelease \
110+
-pl xapi-model,xapi-client,xapi-model-spring-boot-starter -am \
111+
-DskipTests
112+
env:
113+
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
114+
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
115+
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
116+
117+
- name: Update to next development version
118+
run: |
119+
NEXT_VERSION="${{ steps.validate_tag.outputs.next_version }}"
120+
echo "Setting next development version to: $NEXT_VERSION"
121+
122+
# Update to next SNAPSHOT version
123+
./mvnw -B versions:set -DnewVersion="${NEXT_VERSION}" -DgenerateBackupPoms=false
124+
125+
# Commit the version change
126+
git add .
127+
git commit -m "[maven-release-plugin] prepare for next development iteration"
128+
129+
- name: Update release tag to point to release commit
130+
run: |
131+
TAG_NAME="${{ github.event.release.tag_name }}"
132+
133+
# Delete the existing tag locally
134+
git tag -d "$TAG_NAME"
135+
136+
# Get the commit hash of the release preparation commit (one before current)
137+
RELEASE_COMMIT=$(git rev-parse HEAD~1)
138+
139+
# Create new tag pointing to the release commit
140+
git tag -a "$TAG_NAME" "$RELEASE_COMMIT" -m "Release $TAG_NAME"
141+
142+
# Force push the updated tag
143+
git push -f origin "$TAG_NAME"
144+
145+
echo "Updated tag $TAG_NAME to point to release commit: $RELEASE_COMMIT"
146+
147+
- name: Push release branch
148+
run: |
149+
RELEASE_BRANCH="${{ steps.validate_tag.outputs.release_branch }}"
150+
151+
# Push the release branch with all commits
152+
git push -u origin "$RELEASE_BRANCH"
153+
154+
echo "Pushed release branch: $RELEASE_BRANCH"
155+
156+
- name: Clean up
157+
if: always()
158+
run: |
159+
# Clean up any Maven artifacts
160+
rm -f release.properties
161+
find . -name "pom.xml.versionsBackup" -delete || true

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,7 @@ public ResponseEntity<Collection<UUID>> postStatements(
488488
}
489489

490490
```
491+
492+
## Contributing
493+
494+
For information about creating releases, see [RELEASING.md](RELEASING.md).

RELEASING.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Release Process
2+
3+
This document describes the automated release process for xAPI Java.
4+
5+
## Automated Release Process
6+
7+
The release process is fully automated via GitHub Actions. To create a new release:
8+
9+
### Step 1: Create a GitHub Release
10+
11+
1. Navigate to the [Releases page](https://github.com/BerryCloud/xapi-java/releases)
12+
2. Click **"Draft a new release"**
13+
3. Enter the tag version in the format: `vX.Y.Z` (e.g., `v1.2.0`)
14+
- The tag **must** start with `v` followed by semantic version numbers
15+
- Example: `v1.1.16`, `v2.0.0`, `v1.2.3`
16+
4. Enter a release title (e.g., "Release 1.2.0")
17+
5. Add release notes describing the changes
18+
6. Click **"Publish release"**
19+
20+
### Step 2: Automated Workflow Execution
21+
22+
Once you publish the release, the "Automated Release" workflow will:
23+
24+
1. ✅ Validate the tag format
25+
2. ✅ Extract the version number from the tag
26+
3. ✅ Create a `release-X.Y.Z` branch from the release tag
27+
4. ✅ Update all `pom.xml` files to the release version
28+
5. ✅ Commit the version change
29+
6. ✅ Build and deploy artifacts to Maven Central with:
30+
- Compiled JARs
31+
- Source JARs
32+
- Javadoc JARs
33+
- GPG signatures
34+
7. ✅ Update the release tag to point to the release commit
35+
8. ✅ Update `pom.xml` files to the next SNAPSHOT version
36+
9. ✅ Push all commits to the release branch
37+
38+
### Step 3: Verify Release
39+
40+
1. Check the [Actions tab](https://github.com/BerryCloud/xapi-java/actions) to ensure the workflow completed successfully
41+
2. Verify the release branch was created: `release-X.Y.Z`
42+
3. Verify artifacts are available on [Maven Central](https://central.sonatype.com/artifact/dev.learning.xapi/xapi-model)
43+
44+
## Release Branch Strategy
45+
46+
- **Main branch (`main`)**: Contains development code with `-SNAPSHOT` versions
47+
- **Release branches (`release-X.Y.Z`)**: Created automatically for each release
48+
- Contains two commits:
49+
1. Version update to release version (X.Y.Z)
50+
2. Version update to next development version (X.Y.Z+1-SNAPSHOT)
51+
- **Release tags (`vX.Y.Z`)**: Points to the release version commit
52+
53+
## Version Numbering
54+
55+
This project follows [Semantic Versioning](https://semver.org/):
56+
57+
- **MAJOR** version (X): Incompatible API changes
58+
- **MINOR** version (Y): Backward-compatible functionality additions
59+
- **PATCH** version (Z): Backward-compatible bug fixes
60+
61+
The automated workflow increments the **PATCH** version for the next development iteration.
62+
63+
## Manual Override (Not Recommended)
64+
65+
For special cases, you can still manually trigger the deprecated "Maven Release (Manual)" workflow:
66+
67+
1. Go to [Actions](https://github.com/BerryCloud/xapi-java/actions)
68+
2. Select "Maven Release (Manual - Deprecated)"
69+
3. Click "Run workflow"
70+
71+
**Note**: This method is deprecated and should only be used if the automated process fails.
72+
73+
## Troubleshooting
74+
75+
### Release Workflow Failed
76+
77+
If the automated release workflow fails:
78+
79+
1. Check the workflow logs in the Actions tab
80+
2. Common issues:
81+
- Invalid tag format (must be `vX.Y.Z`)
82+
- Missing secrets (GPG keys, Maven credentials)
83+
- Build or test failures
84+
3. You can re-run the workflow after fixing issues
85+
86+
### Release Branch Already Exists
87+
88+
If you need to re-release the same version:
89+
90+
1. Delete the existing release branch: `git push origin --delete release-X.Y.Z`
91+
2. Delete the release and tag in GitHub UI
92+
3. Create a new release with the same version
93+
94+
## Required Secrets
95+
96+
The following GitHub secrets must be configured for releases to work:
97+
98+
- `OSSRH_USERNAME`: Sonatype OSSRH username
99+
- `OSSRH_TOKEN`: Sonatype OSSRH token
100+
- `MAVEN_GPG_PRIVATE_KEY`: GPG private key for signing artifacts
101+
- `MAVEN_GPG_PASSPHRASE`: Passphrase for the GPG private key
102+
103+
## Snapshot Releases
104+
105+
Snapshot versions are automatically published to Maven Central's snapshot repository when changes are pushed to `release-*` branches. See the "Publish snapshot to the Sonatype OSSRH" workflow.

0 commit comments

Comments
 (0)