diff --git a/.github/CompatibilityUtils.java b/.build/CompatibilityUtils.java
similarity index 100%
rename from .github/CompatibilityUtils.java
rename to .build/CompatibilityUtils.java
diff --git a/.github/Helper.java b/.build/Helper.java
similarity index 100%
rename from .github/Helper.java
rename to .build/Helper.java
diff --git a/.github/PreRelease.java b/.build/PreRelease.java
similarity index 100%
rename from .github/PreRelease.java
rename to .build/PreRelease.java
diff --git a/.github/PulsarConfigDoc.java b/.build/PulsarConfigDoc.java
similarity index 98%
rename from .github/PulsarConfigDoc.java
rename to .build/PulsarConfigDoc.java
index 78c394e96e..c3b5a52998 100755
--- a/.github/PulsarConfigDoc.java
+++ b/.build/PulsarConfigDoc.java
@@ -34,7 +34,7 @@
* - Config file (whether the property is settable from a configuration file
* - Default value
*
- * Run with `.github/PulsarConfigDoc.java -d documentation/src/main/docs/pulsar/config`
+ * Run with `.build/PulsarConfigDoc.java -d documentation/src/main/docs/pulsar/config`
*
*/
@CommandLine.Command(name = "pulsar-config-doc", mixinStandardHelpOptions = true, version = "0.1",
diff --git a/.github/ci-maven-settings.xml b/.build/ci-maven-settings.xml
similarity index 100%
rename from .github/ci-maven-settings.xml
rename to .build/ci-maven-settings.xml
diff --git a/.github/maven-settings.xml.gpg b/.build/maven-settings.xml.gpg
similarity index 100%
rename from .github/maven-settings.xml.gpg
rename to .build/maven-settings.xml.gpg
diff --git a/.github/smallrye-sign.asc.gpg b/.build/smallrye-sign.asc.gpg
similarity index 100%
rename from .github/smallrye-sign.asc.gpg
rename to .build/smallrye-sign.asc.gpg
diff --git a/.github/PostRelease.java b/.github/PostRelease.java
deleted file mode 100755
index 9d70f27989..0000000000
--- a/.github/PostRelease.java
+++ /dev/null
@@ -1,164 +0,0 @@
-///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS org.kohsuke:github-api:1.117
-//DEPS info.picocli:picocli:4.5.0
-//SOURCES Helper.java
-
-import org.kohsuke.github.*;
-import picocli.CommandLine;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.Callable;
-import java.util.stream.Collectors;
-
-import static helpers.Helper.*;
-
-/**
- * Script run after the release.
- * The script does the following action in this order:
- * - checks that the previous milestone is closed, close it if not
- * - checks that the next milestone exists, or create it if not
- * - creates the Github release and compute the release notes
- *
- * Run with `./PostRelease.java --token=GITHUB_TOKEN --release-version=version
- *
- * 1. The github token is mandatory.
- *
- * The version is taken from the last tag if not set.
- */
-@CommandLine.Command(name = "post-release", mixinStandardHelpOptions = true, version = "0.1",
- description = "Post-Release Check")
-public class PostRelease implements Callable {
-
- @CommandLine.Option(names = "--token", description = "The Github Token", required = true)
- private String token;
-
- @CommandLine.Option(names = "--release-version", description = "Set the released version", required = true)
- private String releaseVersion;
-
- private static final String REPO = "smallrye/smallrye-reactive-messaging";
-
- public static void main(String... args) {
- int exitCode = new CommandLine(new PostRelease()).execute(args);
- System.exit(exitCode);
- }
-
- @Override
- public Integer call() throws Exception {
- GitHub gitHub = new GitHubBuilder().withOAuthToken(token).build();
- GHRepository repository = gitHub.getRepository(REPO);
-
- List tags = repository.listTags().toList();
- List milestones = repository.listMilestones(GHIssueState.ALL).toList();
-
- info("Running post-release checks for release %s", releaseVersion);
-
- // Check that the tag associated with the release version exists
- GHTag tag = getTag(releaseVersion, tags);
-
- assert tag != null;
-
- // Check that the milestone exists (this check has already been done during the pre-release checks, just to be double sure)
- GHMilestone milestone = milestones.stream().filter(m -> m.getTitle().equals(releaseVersion)).findFirst()
- .orElse(null);
- failIfTrue(() -> milestone == null, "Unable to find the milestone %s", releaseVersion);
- assert milestone != null;
- success("Milestone %s found (%s)", milestone.getTitle(), milestone.getHtmlUrl());
-
- success("Post-release check successful");
- info("Starting post-release tasks");
-
- // Close milestone
- if (milestone.getState() != GHMilestoneState.CLOSED) {
- milestone.close();
- success("Milestone %s closed (%s)", milestone.getTitle(), milestone.getHtmlUrl());
- } else {
- success("Milestone %s already closed (%s)", milestone.getTitle(), milestone.getHtmlUrl());
- }
-
- // Compute next version
- String nextVersion = getNextVersion(releaseVersion);
- success("Next version will be %s", nextVersion);
-
- // Create new milestone if it does not already exist
- GHMilestone nextMilestone = milestones.stream().filter(m -> m.getTitle().equals(nextVersion)).findFirst()
- .orElse(null);
- if (nextMilestone != null) {
- success("Next milestone (%s) already exists: %s", nextMilestone.getTitle(), nextMilestone.getHtmlUrl());
- } else {
- nextMilestone = repository.createMilestone(nextVersion, null);
- success("Next milestone (%s) created: %s", nextMilestone.getTitle(), nextMilestone.getHtmlUrl());
- }
-
- // Compute the release notes and create releases
- List issues = repository.getIssues(GHIssueState.CLOSED, milestone);
- String description = createReleaseDescription(issues);
- // Check if release already exists
- GHRelease existingRelease = repository.getReleaseByTagName(tag.getName());
- if (existingRelease != null) {
- info("Release %s already exists (%s) - skip release note generation", existingRelease.getName(), existingRelease.getHtmlUrl());
- info("Generated release notes:\n%s", description);
-
- if (existingRelease.isDraft()) {
- existingRelease.update().draft(false);
- success("Marked release %s as non-draft", existingRelease.getName());
- }
- } else {
- GHRelease release = repository.createRelease(releaseVersion)
- .name(releaseVersion)
- .body(description)
- .create();
- success("Release %s created: %s", releaseVersion, release.getHtmlUrl());
- }
-
- completed("Post-Release done!");
-
- return 0;
- }
-
- private GHTag getTag(String releaseVersion, List tags) {
- failIfTrue(tags::isEmpty, "No tags found in repository");
- Optional first = tags.stream().filter(tag -> tag.getName().equals(releaseVersion)).findFirst();
- if (first.isPresent()) {
- success("Tag %s found", releaseVersion);
- return first.get();
- }
- fail("Unable to find the tag %s in the repository", releaseVersion);
- return null;
- }
-
- private String getNextVersion(String v) {
- String[] segments = v.split("\\.");
- if (segments.length < 3) {
- fail("Invalid version %s, number of segments must be at least 3, found %d", v, segments.length);
- }
-
- return String.format("%s.%d.0", segments[0], Integer.parseInt(segments[1]) + 1);
- }
-
- private String createReleaseDescription(List issues) throws IOException {
- File file = new File("target/differences.md");
- String compatibility = "";
- if (file.isFile()) {
- compatibility += new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
- }
-
- StringBuilder desc = new StringBuilder();
- desc.append("### Changelog\n\n");
- List list = issues.stream().map(this::line).collect(Collectors.toList());
- desc.append(String.join("\n", list));
- desc.append("\n");
-
- desc.append(compatibility).append("\n");
- return desc.toString();
- }
-
- private String line(GHIssue issue) {
- return String.format(" * [#%d](%s) - %s", issue.getNumber(), issue.getHtmlUrl(), issue.getTitle());
- }
-
-}
diff --git a/.github/decrypt-secrets.sh b/.github/decrypt-secrets.sh
deleted file mode 100644
index f8159b76e1..0000000000
--- a/.github/decrypt-secrets.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-
-echo "Decrypting smallrye signature"
-gpg --quiet --batch --yes --decrypt --passphrase="${SECRET_FILES_PASSPHRASE}" \
- --output smallrye-sign.asc .github/smallrye-sign.asc.gpg
-
-echo "Decrypting Maven settings"
-gpg --quiet --batch --yes --decrypt --passphrase="${SECRET_FILES_PASSPHRASE}" \
- --output maven-settings.xml .github/maven-settings.xml.gpg
diff --git a/.github/deploy-doc.sh b/.github/deploy-doc.sh
deleted file mode 100755
index cc0dbb9279..0000000000
--- a/.github/deploy-doc.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-VERSION=${1:-"$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)"}
-REMOTE=${2:-"origin"}
-REMOTE_URL=$(git remote get-url "${REMOTE}")
-
-echo "Deploying documentation version ${VERSION} to remote ${REMOTE} (${REMOTE_URL})"
-
-echo "Configuring environment"
-cd documentation
-pipenv install
-
-echo "Publishing"
-mvn -B clean compile
-pipenv run mike deploy --update-aliases --push --remote "${REMOTE}" "${VERSION}" "latest"
-pipenv --rm
-
-echo "Done"
diff --git a/.github/deploy.sh b/.github/deploy.sh
deleted file mode 100644
index 5e121c36c8..0000000000
--- a/.github/deploy.sh
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-export TARGET=$1
-
-init_gpg() {
- gpg2 --fast-import --no-tty --batch --yes smallrye-sign.asc
-}
-
-init_git() {
- git config --global user.name "${GITHUB_ACTOR}"
- git config --global user.email "smallrye@googlegroups.com"
-
- git update-index --assume-unchanged .github/deploy.sh
- git update-index --assume-unchanged .github/decrypt-secrets.sh
- git update-index --assume-unchanged .github/deploy-doc.sh
-}
-
-compatibility_extract() {
- echo "Extracting compatibility report"
- jbang .github/CompatibilityUtils.java extract
-}
-
-compatibility_clear() {
- echo "Clearing difference justifications"
- jbang .github/CompatibilityUtils.java clear
- if [[ $(git diff --stat) != '' ]]; then
- git add -A
- git status
- git commit -m "[POST-RELEASE] - Clearing breaking change justifications"
- git push origin main
- else
- echo "No justifications cleared"
- fi
-}
-
-deploy_release() {
- export RELEASE_VERSION=""
- export BRANCH="HEAD"
- export NEXT_VERSION=""
-
- if [ -f /tmp/release-version ]; then
- RELEASE_VERSION=$(cat /tmp/release-version)
- else
- echo "'/tmp/release-version' required"
- exit 1
- fi
-
- echo "Cutting release ${RELEASE_VERSION}"
- mvn -B -fn clean
- git checkout ${BRANCH}
- HASH=$(git rev-parse --verify $BRANCH)
- echo "Last commit is ${HASH} - creating detached branch"
- git checkout -b "r${RELEASE_VERSION}" "${HASH}"
-
- echo "Update version to ${RELEASE_VERSION}"
- mvn -B versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false -s maven-settings.xml
- mvn -B clean verify -DskipTests -Prelease -s maven-settings.xml
-
- git commit -am "[RELEASE] - Bump version to ${RELEASE_VERSION}"
- git tag "${RELEASE_VERSION}"
- echo "Pushing tag to origin"
- git push origin "${RELEASE_VERSION}"
-
- echo "Deploying release artifacts"
- mvn -B deploy -DskipTests -Prelease -s maven-settings.xml
-
- echo "Building documentation"
- .github/deploy-doc.sh
-
- if [ -f /tmp/next-version ]; then
- NEXT_VERSION=$(cat /tmp/next-version)
- echo "Setting main version to ${NEXT_VERSION}-SNAPSHOT"
- git reset --hard
- git checkout main
- mvn -B versions:set -DnewVersion="${NEXT_VERSION}-SNAPSHOT" -DgenerateBackupPoms=false -s maven-settings.xml
- git commit -am "[RELEASE] - Bump main branch to ${NEXT_VERSION}-SNAPSHOT"
- git push origin main
- echo "Main branch updated"
- else
- echo "No next version - skip updating the main version"
- fi
-}
-
-init_git
-init_gpg
-
-if [[ ${TARGET} == "release" ]]; then
- echo "Checking release prerequisites"
- echo "Milestone set to ${MILESTONE}"
- .github/Prelease.java --token="${GITHUB_TOKEN}" --release-version="${MILESTONE}"
-
- deploy_release
-
- echo "Executing post-release"
- compatibility_extract
- .github/PostRelease.java --token="${GITHUB_TOKEN}"
- compatibility_clear
-else
- echo "Unknown environment: ${TARGET}"
-fi
diff --git a/.github/workflows/build-main-branches.yml b/.github/workflows/build-main-branches.yml
index dfd4079f34..80c1c644de 100644
--- a/.github/workflows/build-main-branches.yml
+++ b/.github/workflows/build-main-branches.yml
@@ -53,7 +53,7 @@ jobs:
env:
MAVEN_OPTS: ${{ matrix.java.opts }}
run: |
- mvn -s .github/ci-maven-settings.xml -Dmaven.resolver.transport=wagon -B \
+ mvn -s .build/ci-maven-settings.xml -Dmaven.resolver.transport=wagon -B \
clean install -Dtest-containers=true ${{ matrix.java.build_opts }}
quality:
@@ -76,7 +76,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_LOGIN }}
run: |
- mvn -s .github/ci-maven-settings.xml -B \
+ mvn -s .build/ci-maven-settings.xml -B \
clean install sonar:sonar -Pcoverage \
-Dmaven.resolver.transport=wagon \
-Drevapi.skip=true \
diff --git a/.github/workflows/build-podman.yml b/.github/workflows/build-podman.yml
index d39f480099..51704eed1e 100644
--- a/.github/workflows/build-podman.yml
+++ b/.github/workflows/build-podman.yml
@@ -72,5 +72,5 @@ jobs:
env:
MAVEN_OPTS: ${{ matrix.java.opts }}
run: |
- mvn -s .github/ci-maven-settings.xml -Dmaven.resolver.transport=wagon -B \
+ mvn -s .build/ci-maven-settings.xml -Dmaven.resolver.transport=wagon -B \
clean install -Dtest-containers=true ${{ matrix.java.build_opts }}
diff --git a/.github/workflows/build-pull.yml b/.github/workflows/build-pull.yml
index 73532f91e1..64d7e3a451 100644
--- a/.github/workflows/build-pull.yml
+++ b/.github/workflows/build-pull.yml
@@ -52,7 +52,7 @@ jobs:
env:
MAVEN_OPTS: ${{ matrix.java.opts }}
run: |
- mvn -s .github/ci-maven-settings.xml -Dmaven.resolver.transport=wagon \
+ mvn -s .build/ci-maven-settings.xml -Dmaven.resolver.transport=wagon \
-B clean install -Pcoverage -Dtest-containers=true ${{ matrix.java.build_opts }}
- name: Codecov
uses: codecov/codecov-action@v1.0.13
diff --git a/.github/workflows/push-release-to-maven-central.yml b/.github/workflows/push-release-to-maven-central.yml
new file mode 100644
index 0000000000..b5d3382f5a
--- /dev/null
+++ b/.github/workflows/push-release-to-maven-central.yml
@@ -0,0 +1,25 @@
+name: Push a release to Maven Central
+
+on:
+ push:
+ tags:
+ - '4.*'
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ env:
+ SECRET_FILES_PASSPHRASE: ${{ secrets.SECRET_FILES_PASSPHRASE }}
+ steps:
+ - name: Git checkout
+ uses: actions/checkout@v4
+ - name: Java setup
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+ - name: Install just
+ uses: taiki-e/install-action@just
+ - name: Deploy to Maven Central
+ run: just deploy-to-maven-central
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..0c5465a052
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,58 @@
+name: Release Smallrye Reactive Messaging
+
+on:
+ workflow_dispatch:
+ inputs:
+ previousVersion:
+ description: 'Previous version'
+ required: true
+ version:
+ description: 'Release version'
+ required: true
+ deployWebsite:
+ description: 'Shall we deploy the website?'
+ required: true
+ default: 'true'
+ clearRevAPI:
+ description: 'Shall we clear RevAPI justifications?'
+ required: true
+ default: 'true'
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ env:
+ GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+ RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+ SECRET_FILES_PASSPHRASE: ${{ secrets.SECRET_FILES_PASSPHRASE }}
+ RELEASE_VERSION: ${{ github.event.inputs.version }}
+ DEPLOY_WEBSITE: ${{ github.event.inputs.deployWebsite }}
+ CLEAR_REVAPI: ${{ github.event.inputs.clearRevAPI }}
+ JRELEASER_TAG_NAME: ${{ github.event.inputs.version }}
+ JRELEASER_PREVIOUS_TAG_NAME: ${{ github.event.inputs.previousVersion }}
+ JRELEASER_GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+
+ steps:
+ - name: Git checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ token: ${{ secrets.RELEASE_TOKEN }}
+ - name: Java setup
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+ - name: Install just
+ uses: taiki-e/install-action@just
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: 3.x
+ - name: Install JBang with sdkman
+ uses: sdkman/sdkman-action@v1
+ with:
+ candidate: jbang
+ - name: Perform the release steps
+ run: just perform-release
diff --git a/justfile b/justfile
new file mode 100755
index 0000000000..0720e12605
--- /dev/null
+++ b/justfile
@@ -0,0 +1,116 @@
+set shell := ["bash", "-uc"]
+
+# Just echo the purpose of this file
+_default:
+ @echo "This file is used to automate some release tasks"
+ @echo "(running in `pwd`)"
+ @just --list
+
+# Build locally without tests
+build:
+ @echo "Building locally without tests"
+ ./mvnw clean install -DskipTests -T1C
+
+# Build locally with tests
+test:
+ @echo "Testing locally"
+ ./mvnw clean verify
+
+# Build on CI without tests
+build-ci:
+ ./mvnw -B -ntp -s .build/ci-maven-settings.xml clean verify -DskipTests
+
+# Test on CI with tests
+test-ci:
+ ./mvnw -B -ntp -s .build/ci-maven-settings.xml clean verify
+
+# Perform a release
+perform-release: pre-release release post-release
+ @echo "🎉 Successfully released Smallrye Reactive Messaging ${RELEASE_VERSION} 🚀"
+
+# Decrypt secrets
+decrypt-secrets:
+ @if [[ -z "${SECRET_FILES_PASSPHRASE}" ]]; then exit 1; fi
+ @echo "🔐 Decrypting smallrye signature"
+ gpg --quiet --batch --yes --decrypt --passphrase="${SECRET_FILES_PASSPHRASE}" \
+ --output smallrye-sign.asc .build/smallrye-sign.asc.gpg
+ @echo "🔐 Decrypting Maven settings"
+ gpg --quiet --batch --yes --decrypt --passphrase="${SECRET_FILES_PASSPHRASE}" \
+ --output maven-settings.xml .build/maven-settings.xml.gpg
+
+# Initialize GnuPG
+init-gpg:
+ @echo "🔐 GnuPG setup"
+ gpg --fast-import --no-tty --batch --yes smallrye-sign.asc
+
+# Initialize Git
+init-git:
+ @echo "🔀 Git setup"
+ git config --global user.name "smallrye-ci"
+ git config --global user.email "smallrye@googlegroups.com"
+
+# Steps before releasing
+pre-release: decrypt-secrets init-gpg init-git
+ @echo "🚀 Pre-release steps..."
+ @if [[ -z "${RELEASE_TOKEN}" ]]; then exit 1; fi
+ @if [[ -z "${RELEASE_VERSION}" ]]; then exit 1; fi
+ @echo "Pre-release verifications"
+ jbang .build/PreRelease.java --token=${RELEASE_TOKEN} --release-version=${RELEASE_VERSION}
+ @echo "Bump project version to ${RELEASE_VERSION}"
+ ./mvnw -B -ntp versions:set -DnewVersion=${RELEASE_VERSION} -DgenerateBackupPoms=false -s .build/ci-maven-settings.xml
+ @echo "Check that the project builds (no tests)"
+ ./mvnw -B -ntp clean install -Prelease -DskipTests -s maven-settings.xml
+ @echo "Check that the website builds"
+ -[[ ${DEPLOY_WEBSITE} == "true" ]] && cd documentation && pipenv install && pipenv run mkdocs build
+
+# Steps to release
+release: pre-release
+ @echo "🚀 Release steps..."
+ @if [[ -z "${JRELEASER_TAG_NAME}" ]]; then exit 1; fi
+ @if [[ -z "${JRELEASER_PREVIOUS_TAG_NAME}" ]]; then exit 1; fi
+ @if [[ -z "${JRELEASER_GITHUB_TOKEN}" ]]; then exit 1; fi
+ @echo "Commit release version and push upstream"
+ git commit -am "[RELEASE] - Bump version to ${RELEASE_VERSION}"
+ git push
+ jbang .build/CompatibilityUtils.java extract
+ @echo "Call JReleaser"
+ ./mvnw -B -ntp jreleaser:full-release -Pjreleaser -pl :smallrye-reactive-messaging -s .build/ci-maven-settings.xml
+ @echo "Bump to 999-SNAPSHOT and push upstream"
+ ./mvnw -B -ntp versions:set -DnewVersion=999-SNAPSHOT -DgenerateBackupPoms=false -s .build/ci-maven-settings.xml
+ git commit -am "[RELEASE] - Next development version: 999-SNAPSHOT"
+ git push
+
+# Deploy to Maven Central
+deploy-to-maven-central: decrypt-secrets init-gpg
+ @echo "🔖 Deploy to Maven Central"
+ ./mvnw -B -ntp deploy -Prelease -DskipTests -s maven-settings.xml
+
+# Steps post-release
+post-release:
+ @echo "🚀 Post-release steps..."
+ -[[ ${CLEAR_REVAPI} == "true" ]] && just clear-revapi
+ -[[ ${DEPLOY_WEBSITE} == "true" ]] && just deploy-docs
+
+# Update Pulsar Connector Configuration Documentation
+update-pulsar-config-docs:
+ @echo "📝 Updating Pulsar connector configuration docs"
+ jbang .build/PulsarConfigDoc.java -d documentation/src/main/docs/pulsar/config
+
+# Deploy documentation
+deploy-docs:
+ @echo "📝 Deploying documentation to GitHub"
+ @if [[ -z "${RELEASE_VERSION}" ]]; then exit 1; fi
+ ./mvnw -B -ntp clean compile -f documentation && cd documentation && pipenv install && pipenv run mike deploy --update-aliases --push --remote origin "${RELEASE_VERSION}" "latest"
+
+# Clear RevAPI justifications
+clear-revapi:
+ #!/usr/bin/env bash
+ jbang .build/CompatibilityUtils.java clear
+ if [[ $(git diff --stat) != '' ]]; then
+ git add -A
+ git status
+ git commit -m "[POST-RELEASE] - Clearing breaking change justifications"
+ git push
+ else
+ echo "No justifications cleared"
+ fi