diff --git a/.github/maintainers_guide.md b/.github/maintainers_guide.md
index 82ba9dae0..3a7f14ad2 100644
--- a/.github/maintainers_guide.md
+++ b/.github/maintainers_guide.md
@@ -106,58 +106,11 @@ Refer to the [README](https://github.com/slackapi/java-slack-sdk/blob/main/docs/
### Releasing
-#### Prerequisites
-
-* If you don't have `gnu-sed`, run `brew install gnu-sed` & `brew install gnupg`
-* Make sure you've set up your key https://central.sonatype.org/publish/requirements/gpg/
-* Make sure the account you are using has the permission to make releases [under com.slack groupId](https://central.sonatype.com/publishing/com.slack/users)
-
-Place `$HOME/.m2/settings.xml` with your Sonatype account information.
-* Generate user token: https://central.sonatype.org/publish/generate-portal-token/
-* Set the user token id/password: https://central.sonatype.org/publish/publish-portal-maven/#credentials
-
-```xml
-
- /${your-home-dir}/.m2/repository
-
-
- central
- ${your-username}
- ${your-password}
-
-
- central-snapshots
- ${your-username}
- ${your-password}
-
-
-
- org.apache.maven.plugins
- org.codehaus.mojo
-
-
-```
-
#### Snapshot Release
-Snapshot releases are intended for developers to make pre-release versions of their projects available for testing.
-To learn more about snapshot releases in maven central repository check out [publish-portal-snapshots](https://central.sonatype.org/publish/publish-portal-snapshots/)
+Snapshot releases are published by starting and approving the [release workflow](https://github.com/slackapi/java-slack-sdk/actions/workflows/release.yml) with `workflow_dispatch` for any branch with a `-SNAPSHOT` version, including the `main` branch.
-* From the upstream repository
-* Preparation
- * `git switch main && git pull origin main` (or the branch you want to release from)
- * Make sure there are no build failures at https://github.com/slackapi/java-slack-sdk/actions
-* Set a new version
- * It is **critical** that the version ends with `-SNAPSHOT`. This is how [central-publishing-maven-plugin](https://central.sonatype.org/publish/publish-portal-snapshots/#publishing-with-the-central-publishing-maven-plugin) automatically recognizes snapshot releases and uploads them the right location.
- * If you don't have `gnu-sed`, check out [Prerequisites](#prerequisites)
- * Run `scripts/set_version.sh (the version)` (e.g., `scripts/set_version.sh 1.0.0-SNAPSHOT`)
-* Ship the libraries
- * Switch to **JDK 17** to publish all modules (on macOS, you can run `export JAVA_HOME=$(/usr/libexec/java_home -v 17)` for it)
- * Run `scripts/release.sh` (it takes a bit long)
- * (If you encounter an error, log in https://oss.sonatype.org/ to check detailed information)
-* No need to create a GitHub Release, since this is intended for developers to make pre-release versions of their projects.
-* `-SNAPSHOT` versions are intended to be overwritten.
- * This enables developers to work with the latest version of a library without needing to update their dependencies repeatedly.
+These `-SNAPSHOT` versions are intended to be overwritten. This enables developers to work with the latest version of a library without needing to update their dependencies repeatedly. To learn more about snapshot releases in maven central repository check out [publish-portal-snapshots](https://central.sonatype.org/publish/publish-portal-snapshots/).
#### Stable Release
@@ -166,19 +119,16 @@ To learn more about snapshot releases in maven central repository check out [pub
* `git switch main && git pull origin main`
* Make sure there are no build failures at https://github.com/slackapi/java-slack-sdk/actions
* Set a new version
- * If you don't have `gnu-sed`, check out [Prerequisites](#prerequisites)
- * Run `scripts/set_version.sh (the version)` (e.g., `scripts/set_version.sh 1.0.0`)
-* Ship the libraries
- * Switch to **JDK 17** to publish all modules (on macOS, you can run `export JAVA_HOME=$(/usr/libexec/java_home -v 17)` for it)
- * Run `scripts/release.sh` (it takes a bit long)
- * (If you encounter an error, log in https://oss.sonatype.org/ to check detailed information)
-* Create GitHub Release(s) and add release notes
- * [Look at previous releases](https://github.com/slackapi/java-slack-sdk/releases) and follow their layouts
- * Prepare a release note by `git log --pretty=format:'%h %s by %an' --abbrev-commit | grep -v "Merge pull request " | head -50`
+ * Run `scripts/set_version.sh (the version)` (e.g., `scripts/set_version.sh 1.0.0`) — requires `gnu-sed` on macOS (`brew install gnu-sed`)
* `git add . -v && git commit -m'version (your version here)'`
* `git tag v(your version here)`
- * `git push & git push --tags`
+ * `git push && git push --tags`
+* Publish to Maven Central
+ * Start and approve the [release workflow](https://github.com/slackapi/java-slack-sdk/actions/workflows/release.yml) using `workflow_dispatch` on `main`
+* Create a GitHub Release
* Open https://github.com/slackapi/java-slack-sdk/releases/new?tag=v${version}
+ * [Look at previous releases](https://github.com/slackapi/java-slack-sdk/releases) and follow their layouts
+ * Prepare a release note by `git log --pretty=format:'%h %s by %an' --abbrev-commit | grep -v "Merge pull request " | head -50`
* (Slack Internal) Communicate the release internally. Include a link to the GitHub Release(s).
* (Slack Internal) Tweet? Not necessary for patch updates, might be needed for minor updates, definitely needed for
major updates. Include a link to the GitHub Release(s).
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..d09765896
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,61 @@
+name: Release
+
+on:
+ workflow_dispatch:
+
+jobs:
+ publish:
+ name: Publish
+ if: github.repository == 'slackapi/java-slack-sdk'
+ runs-on: ubuntu-latest
+ environment: central
+ permissions:
+ contents: read
+ steps:
+ - name: Checkout the repo
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
+ with:
+ persist-credentials: false
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0
+ with:
+ java-version: "17"
+ distribution: "adopt"
+ server-id: central
+ server-username: MAVEN_USERNAME
+ server-password: MAVEN_PASSWORD
+ gpg-private-key: ${{ secrets.GPG_KEY }}
+ gpg-passphrase: MAVEN_GPG_PASSPHRASE
+
+ - name: Add snapshot server credentials
+ run: |
+ sed -i '/<\/servers>/i \
+ \
+ central-snapshots\
+ ${env.MAVEN_USERNAME}\
+ ${env.MAVEN_PASSWORD}\
+ ' ~/.m2/settings.xml
+
+ - name: Configure GPG
+ run: |
+ echo "use-agent" >> ~/.gnupg/gpg.conf
+ echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
+ echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
+ echo RELOADAGENT | gpg-connect-agent
+
+ - name: Publish to Maven Central
+ run: |
+ ./mvnw clean deploy \
+ -P production-releases \
+ -D maven.test.skip=true \
+ -D gpg.passphrase="${MAVEN_GPG_PASSPHRASE}" \
+ -pl !bolt-kotlin-examples \
+ -pl !bolt-quarkus-examples \
+ --batch-mode \
+ --no-transfer-progress
+ env:
+ MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
+ MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ MAVEN_OPTS: "--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED"
diff --git a/AGENTS.md b/AGENTS.md
index 204e4de22..220570548 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -608,8 +608,8 @@ Documentation: https://docs.slack.dev/tools/java-slack-sdk/guides/bolt-basics
Releases publish all modules simultaneously to Maven Central via Sonatype.
-- **Snapshot**: Version must end with `-SNAPSHOT`. Run `scripts/set_version.sh 1.x.y-SNAPSHOT` then `scripts/release.sh`
-- **Stable**: Run `scripts/set_version.sh 1.x.y` then `scripts/release.sh`. Requires JDK 17, GPG signing, and Sonatype credentials in `~/.m2/settings.xml`
+- **Snapshot**: Trigger the [release workflow](.github/workflows/release.yml) via `workflow_dispatch` on any branch with a `-SNAPSHOT` version.
+- **Stable**: Run `scripts/set_version.sh 1.x.y`, commit, tag `v1.x.y`, push to `main`, then trigger the [release workflow](.github/workflows/release.yml) via `workflow_dispatch`.
- Version is set across all `pom.xml` files AND three generated version classes (generated by `scripts/set_version.sh`):
- `slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java`
- `slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java`
diff --git a/scripts/release.sh b/scripts/release.sh
deleted file mode 100755
index 008d9e163..000000000
--- a/scripts/release.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-is_jdk_8=$(echo "$JAVA_HOME" | grep 8.)
-if [[ "${is_jdk_8}" != "" ]];
-then
- echo "Please use OpenJDK 11 for releasing these libraries."
- exit 1
-fi
-
-exclusion="-pl !bolt-kotlin-examples -pl !bolt-quarkus-examples"
-
-dir=$(dirname "$0")/..
-release_version=$(sed -n 's/^[[:space:]]*\([^\$]\..*\)<\/version>[[:space:]]*$/\1/p' < "${dir}"/pom.xml)
-
-export MAVEN_OPTS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED"
-
-if [[ "${release_version}" =~ ^.+-SNAPSHOT$ ]]; then
- echo "🚀 Releasing a SNAPSHOT version ($release_version) of the project."
- profile=production-releases
- mvn clean \
- deploy \
- -P production-releases \
- -D maven.test.skip=true \
- ${exclusion}
-else
- echo "You are releasing a stable version ($release_version) of the project."
- read -r -p "This will be available publicly. Is this correct? (y/N): " confirmation
-
- if [[ ! "$confirmation" =~ ^[Yy]$ ]]; then
- echo "Release cancelled by user!"
- exit 0
- fi
- echo "Confirmed. Proceeding with the stable release."
-
- profile=production-releases
- mvn clean \
- deploy \
- -P production-releases \
- -D maven.test.skip=true \
- ${exclusion}
-fi