Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
102 changes: 102 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Release

on:
push:
tags:
- 'v*' # e.g., v1.0.4, v1.0.4-SNAPSHOT

concurrency:
group: release-${{ github.ref }}
cancel-in-progress: true

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive

- name: Remove any pre-existing Maven settings.xml
run: rm -f "$HOME/.m2/settings.xml" || true

- name: Set up Temurin JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
cache: maven

- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
git_user_signingkey: false

- name: Configure Maven settings for Sonatype OSSRH
run: |
mkdir -p "$HOME/.m2"
cat > "$HOME/.m2/settings.xml" <<'XML'
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
<localRepository>/home/runner/.m2/repository</localRepository>
<interactiveMode>false</interactiveMode>
<servers>
<server>
<id>central</id>
<username>${env.CENTRAL_USERNAME}</username>
<password>${env.CENTRAL_PASSWORD}</password>
</server>
</servers>
</settings>
XML

- name: Extract version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"

- name: Determine release type (snapshot vs production)
id: reltype
run: |
if [[ "${GITHUB_REF}" == *"-SNAPSHOT" ]]; then
echo "TYPE=snapshot" >> "$GITHUB_OUTPUT"
elif [[ "${GITHUB_REF}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "TYPE=production" >> "$GITHUB_OUTPUT"
else
echo "ERROR: unexpected tag format '${GITHUB_REF}'. Expected vX.Y.Z or vX.Y.Z-SNAPSHOT." >&2
exit 1
fi
Comment thread
dubdabasoduba marked this conversation as resolved.

- name: Set project version from tag
run: |
mvn -B -ntp versions:set -DnewVersion="${{ steps.version.outputs.VERSION }}" -DprocessAllModules=true
mvn -B -ntp versions:commit

- name: Build & Test (signs at verify)
run: mvn -B -ntp clean verify -P release
env:
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

- name: Deploy to Sonatype OSSRH
run: mvn -B -ntp deploy -DskipTests -P release
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
Comment thread
dubdabasoduba marked this conversation as resolved.

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
draft: false
prerelease: ${{ steps.reltype.outputs.TYPE == 'snapshot' }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,42 @@ public class Test {

This is the hello world of Easy Rules. You can find other examples like the [Shop](https://github.com/opensrp/easy-rules/wiki/shop), [Airco](https://github.com/opensrp/easy-rules/wiki/air-conditioning) or [WebApp](https://github.com/opensrp/easy-rules/wiki/web-app) tutorials in the wiki.

## Publishing

Artifacts are published to [Maven Central](https://central.sonatype.com/) automatically when a tag is pushed to the repository.

### Tag conventions

| Type | Pattern | Example | Behaviour |
|------|---------|---------|-----------|
| Release | `v<major>.<minor>.<patch>` | `v4.1.1` | Published to Maven Central; GitHub Release created |
| Snapshot | `v<major>.<minor>.<patch>-SNAPSHOT` | `v4.1.2-SNAPSHOT` | Published to the snapshots repository; GitHub Release marked as pre-release |

```bash
# cut a release
git tag v4.1.1 && git push origin v4.1.1

# cut a snapshot
git tag v4.1.2-SNAPSHOT && git push origin v4.1.2-SNAPSHOT
```

The workflow (`publish.yml`) will:
1. Set the project version from the tag (strips the `v` prefix)
2. Run `mvn clean verify` — compiles and tests the project
3. Run `mvn deploy` — uploads artifacts to Sonatype OSSRH (with release promotion/asset signing handled by the workflow's Maven configuration)
4. Create a GitHub Release automatically

### Required repository secrets

The following secrets must be configured in **Settings → Secrets and variables → Actions**:

| Secret | Description |
|--------|-------------|
| `CENTRAL_USERNAME` | Sonatype Central portal username |
| `CENTRAL_PASSWORD` | Sonatype Central portal token |
| `GPG_PRIVATE_KEY` | Armored GPG private key (`gpg --armor --export-secret-keys <KEY_ID>`) |
| `GPG_PASSPHRASE` | Passphrase for the GPG key |

## Contribution

You are welcome to contribute to the project with pull requests on GitHub.
Expand Down
67 changes: 67 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version>
<maven-javadoc-plugin.version>3.6.3</maven-javadoc-plugin.version>
<maven.source.plugin.version>3.3.1</maven.source.plugin.version>
<maven.gpg.plugin.version>3.2.7</maven.gpg.plugin.version>
<maven-license-plugin.version>4.5</maven-license-plugin.version>
<maven-enforcer-plugin.version>3.4.1</maven-enforcer-plugin.version>
</properties>
Expand Down Expand Up @@ -72,6 +74,12 @@
<role>Lead developer</role>
</roles>
</developer>
<developer>
<name>Ona Systems</name>
<email>info@opensrp.io</email>
<organization>Ona Systems</organization>
<organizationUrl>https://ona.io</organizationUrl>
</developer>
</developers>

<licenses>
Expand Down Expand Up @@ -212,4 +220,63 @@
</plugins>
</build>

<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven.source.plugin.version}</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Sign EVERYTHING at verify so .asc exist before deploy -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${maven.gpg.plugin.version}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Passphrase read automatically from MAVEN_GPG_PASSPHRASE env var -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
Comment thread
dubdabasoduba marked this conversation as resolved.
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Loading