Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/maven-publish.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# DEPRECATED: This workflow is kept for backward compatibility only
#
# Please use the automated release process instead:
# 1. Create a new release in GitHub UI with tag format vX.Y.Z
# 2. The "Automated Release" workflow will handle the rest
#
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven

name: Maven Release
name: Maven Release (Manual - Deprecated)

on: workflow_dispatch
jobs:
Expand Down
168 changes: 168 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# This workflow automates the release process when a release is created on GitHub
# It creates a release branch, updates versions, and deploys to Maven Central
#
# Usage:
# 1. Create a new release in GitHub UI with tag format: vX.Y.Z (e.g., v1.2.0)
# 2. This workflow will automatically:
# - Create a release-X.Y.Z branch
# - Update pom.xml versions to release version
# - Build and deploy artifacts to Maven Central
# - Update pom.xml to next development version
# - Push version commits back to the release branch

name: Automated Release

on:
release:
types: [created] # Trigger when release is created (before it's published)

permissions:
contents: write # Required to create branches and push commits

jobs:
release:
runs-on: ubuntu-latest

steps:
- name: Validate release tag format
id: validate_tag
run: |
TAG_NAME="${{ github.event.release.tag_name }}"
echo "Release tag: $TAG_NAME"

# Validate tag format (should be vX.Y.Z)
if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::Invalid tag format. Expected format: vX.Y.Z (e.g., v1.2.0)"
exit 1
fi

# Remove 'v' prefix to get the version number
VERSION="${TAG_NAME#v}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"

# Create release branch name
RELEASE_BRANCH="release-${VERSION}"
echo "release_branch=${RELEASE_BRANCH}" >> $GITHUB_OUTPUT
echo "Release branch: $RELEASE_BRANCH"

# Calculate next development version (increment patch version)
IFS='.' read -ra VERSION_PARTS <<< "$VERSION"
MAJOR="${VERSION_PARTS[0]}"
MINOR="${VERSION_PARTS[1]}"
PATCH="${VERSION_PARTS[2]}"
NEXT_PATCH=$((PATCH + 1))
NEXT_VERSION="${MAJOR}.${MINOR}.${NEXT_PATCH}-SNAPSHOT"
echo "next_version=${NEXT_VERSION}" >> $GITHUB_OUTPUT
echo "Next development version: $NEXT_VERSION"

- name: Checkout repository at release tag
uses: actions/checkout@v3
with:
ref: ${{ github.event.release.tag_name }}
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
Comment thread
thomasturrell marked this conversation as resolved.

- name: Create release branch
run: |
RELEASE_BRANCH="${{ steps.validate_tag.outputs.release_branch }}"

# Create new branch from the release tag
git checkout -b "$RELEASE_BRANCH"
Comment thread
thomasturrell marked this conversation as resolved.
Outdated
echo "Created branch $RELEASE_BRANCH from tag ${{ github.event.release.tag_name }}"

- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: "17"
distribution: "temurin"
cache: maven
server-id: central
Comment thread
thomasturrell marked this conversation as resolved.
Outdated
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

- name: Set release version in POM
Comment thread
thomasturrell marked this conversation as resolved.
Outdated
run: |
VERSION="${{ steps.validate_tag.outputs.version }}"
echo "Setting version to: $VERSION"

# Use Maven versions plugin to set the version
./mvnw -B versions:set -DnewVersion="${VERSION}" -DgenerateBackupPoms=false

# Commit the version change
git add .
git commit -m "[maven-release-plugin] prepare release v${VERSION}"

- name: Verify release build
run: |
echo "Running tests and verification for release version"

# Build and test the release version
./mvnw -B clean verify

- name: Build and deploy release
run: |
VERSION="${{ steps.validate_tag.outputs.version }}"
echo "Building and deploying version: $VERSION"

# Build and deploy with release profile (includes signing, sources, javadocs)
./mvnw -B clean deploy -Prelease \
-pl xapi-model,xapi-client,xapi-model-spring-boot-starter -am \
-DskipTests
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}

- name: Update to next development version
run: |
NEXT_VERSION="${{ steps.validate_tag.outputs.next_version }}"
echo "Setting next development version to: $NEXT_VERSION"

# Update to next SNAPSHOT version
./mvnw -B versions:set -DnewVersion="${NEXT_VERSION}" -DgenerateBackupPoms=false

# Commit the version change
git add .
git commit -m "[maven-release-plugin] prepare for next development iteration"

- name: Update release tag to point to release commit
run: |
TAG_NAME="${{ github.event.release.tag_name }}"

# Delete the existing tag locally
git tag -d "$TAG_NAME"

# Get the commit hash of the release preparation commit (one before current)
RELEASE_COMMIT=$(git rev-parse HEAD~1)

# Create new tag pointing to the release commit
git tag -a "$TAG_NAME" "$RELEASE_COMMIT" -m "Release $TAG_NAME"

# Force push the updated tag
git push -f origin "$TAG_NAME"

echo "Updated tag $TAG_NAME to point to release commit: $RELEASE_COMMIT"

- name: Push release branch
run: |
RELEASE_BRANCH="${{ steps.validate_tag.outputs.release_branch }}"

# Push the release branch with all commits
git push -u origin "$RELEASE_BRANCH"

echo "Pushed release branch: $RELEASE_BRANCH"

- name: Clean up
Comment thread
thomasturrell marked this conversation as resolved.
Outdated
if: always()
run: |
# Clean up any Maven artifacts
rm -f release.properties
find . -name "pom.xml.versionsBackup" -delete || true
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,7 @@ public ResponseEntity<Collection<UUID>> postStatements(
}

```

## Contributing

For information about creating releases, see [RELEASING.md](RELEASING.md).
178 changes: 178 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Release Process

This document describes the automated release process for xAPI Java.

## Overview

The release process is **fully automated** via GitHub Actions. Creating a release is as simple as:
1. Click "Create Release" in GitHub UI
2. Enter tag (e.g., `v1.2.0`)
3. Publish
4. Wait for workflow to complete βœ…

All version management, building, testing, and deployment happens automatically.

## Automated Release Process

The release process is fully automated via GitHub Actions. To create a new release:
Comment thread
thomasturrell marked this conversation as resolved.
Outdated

### Step 1: Create a GitHub Release

1. Navigate to the [Releases page](https://github.com/BerryCloud/xapi-java/releases)
2. Click **"Draft a new release"**
3. Enter the tag version in the format: `vX.Y.Z` (e.g., `v1.2.0`)
- The tag **must** start with `v` followed by semantic version numbers
- Example: `v1.1.16`, `v2.0.0`, `v1.2.3`
4. Enter a release title (e.g., "Release 1.2.0")
5. Add release notes describing the changes
6. Click **"Publish release"**

### Step 2: Automated Workflow Execution

Once you publish the release, the "Automated Release" workflow will:

1. βœ… Validate the tag format (must be `vX.Y.Z`)
2. βœ… Extract the version number from the tag
3. βœ… Create a `release-X.Y.Z` branch from the release tag
4. βœ… Update all `pom.xml` files to the release version
5. βœ… Commit the version change
6. βœ… **Run full test suite** to verify the release
7. βœ… Build and deploy artifacts to Maven Central with:
- Compiled JARs
- Source JARs
- Javadoc JARs
- GPG signatures
8. βœ… Update the release tag to point to the release commit
9. βœ… Update `pom.xml` files to the next SNAPSHOT version
10. βœ… Push all commits to the release branch

**Workflow Diagram:**
```
User Action: Create Release (tag: v1.2.0)
↓
GitHub: Creates tag v1.2.0 β†’ commit A (from main)
↓
Workflow: Checkout tag v1.2.0
↓
Workflow: Create branch release-1.2.0
↓
Workflow: Update pom.xml to 1.2.0 β†’ commit B
↓
Workflow: Run tests (mvn verify)
↓
Workflow: Build & deploy to Maven Central
↓
Workflow: Move tag v1.2.0 to commit B
↓
Workflow: Update pom.xml to 1.2.1-SNAPSHOT β†’ commit C
↓
Workflow: Push branch release-1.2.0
↓
Result:
- Tag v1.2.0 β†’ commit B (release version)
- Branch release-1.2.0 β†’ commit C (next SNAPSHOT)
- Artifacts deployed to Maven Central
```

### Step 3: Verify Release

1. Check the [Actions tab](https://github.com/BerryCloud/xapi-java/actions) to ensure the workflow completed successfully
2. Verify the release branch was created: `release-X.Y.Z`
3. Verify artifacts are available on [Maven Central](https://central.sonatype.com/artifact/dev.learning.xapi/xapi-model)

## Release Branch Strategy

- **Main branch (`main`)**: Contains development code with `-SNAPSHOT` versions
- **Release branches (`release-X.Y.Z`)**: Created automatically for each release
- Contains two commits:
1. Version update to release version (X.Y.Z)
2. Version update to next development version (X.Y.Z+1-SNAPSHOT)
- **Release tags (`vX.Y.Z`)**: Points to the release version commit

## Version Numbering
Comment thread
thomasturrell marked this conversation as resolved.
Outdated

This project follows [Semantic Versioning](https://semver.org/):

- **MAJOR** version (X): Incompatible API changes
- **MINOR** version (Y): Backward-compatible functionality additions
- **PATCH** version (Z): Backward-compatible bug fixes

The automated workflow increments the **PATCH** version for the next development iteration.

## Manual Override (Not Recommended)
Comment thread
thomasturrell marked this conversation as resolved.
Outdated

For special cases, you can still manually trigger the deprecated "Maven Release (Manual)" workflow:

1. Go to [Actions](https://github.com/BerryCloud/xapi-java/actions)
2. Select "Maven Release (Manual - Deprecated)"
3. Click "Run workflow"

**Note**: This method is deprecated and should only be used if the automated process fails.

## Troubleshooting

### Release Workflow Failed

If the automated release workflow fails:

1. **Check the workflow logs** in the [Actions tab](https://github.com/BerryCloud/xapi-java/actions)
2. **Identify the failed step** and review the error message
3. **Common issues and solutions:**

| Issue | Solution |
|-------|----------|
| Invalid tag format | Use format `vX.Y.Z` (e.g., `v1.2.0`, not `1.2.0` or `v1.2`) |
| Missing secrets | Ensure GPG keys and Maven credentials are configured in repository secrets |
| Build failures | Fix build issues on main branch first, then retry release |
| Test failures | Fix failing tests on main branch first, then retry release |
| Branch already exists | Delete existing branch (see below) before creating new release |
Comment thread
thomasturrell marked this conversation as resolved.
Outdated
| Permission denied | Ensure workflow has `contents: write` permission |
Comment thread
thomasturrell marked this conversation as resolved.
Outdated

4. **After fixing issues:**
- Delete the failed release and tag in GitHub UI
- Delete the release branch if it was created: `git push origin --delete release-X.Y.Z`
- Create a new release with the same tag

### Release Branch Already Exists

If you need to re-release the same version:

1. Delete the existing release branch:
```bash
git push origin --delete release-X.Y.Z
```
2. Delete the existing release in GitHub UI:
- Go to Releases β†’ Click on the release β†’ Delete release
3. Delete the tag:
- Go to Tags β†’ Find the tag β†’ Delete tag
4. Create a new release with the same version tag

### Workflow Stuck or Taking Too Long

The workflow typically takes 5-10 minutes. If it's taking longer:

1. Check if tests are running (this is the longest step)
2. Check for any hanging processes in the workflow logs
3. You can cancel the workflow run and restart it

### Artifacts Not Appearing on Maven Central

If artifacts don't appear on Maven Central after a successful workflow:

1. Check the Central Portal for deployment status: https://central.sonatype.com/
2. Deployment can take up to 2 hours to sync to Maven Central
3. Check for any deployment errors in the workflow logs
4. Verify GPG signing was successful (check for GPG-related errors)

## Required Secrets
Comment thread
thomasturrell marked this conversation as resolved.
Outdated

The following GitHub secrets must be configured for releases to work:

- `OSSRH_USERNAME`: Sonatype OSSRH username
- `OSSRH_TOKEN`: Sonatype OSSRH token
- `MAVEN_GPG_PRIVATE_KEY`: GPG private key for signing artifacts
- `MAVEN_GPG_PASSPHRASE`: Passphrase for the GPG private key

## Snapshot Releases
Comment thread
thomasturrell marked this conversation as resolved.
Outdated

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.