摘要
文章内容核心是使用 Gradle 整合 GitHub Actions 自动化发布 Java 项目至 Maven 仓库。文章内是将项目发布至 sonatype 提供的仓库中。如果你需要自动化发布,或者需要将项目同步至 Maven 中央仓库请仔细阅读。
前期准备
- 可同步 Maven 中央仓库的门票,在 Issues Sonatype 上申请;
- OpenPGP 证书,需要同步至公共的服务器;
- 一个 Java Project;
- GitHub。
关于同步门票部分可参考提供的链接,文章内主要叙述证书相关的内容。
OpenPGP 证书
因我使用的 Windows 操作系统这里使用 Gpg4win 工具生成同步证书。如果你使用的是 Mac 或者 Linux 操作系统可使用其它 GPG 工具如 GnuPG。
安装 Gpg4win
下载地址 Gpg4win。
生成证书
$ gpg --full-generate-key
运行上面的命令按照指示生成 RSA 的证书。
1C:\Users\admin>gpg --full-generate-key 2gpg (GnuPG) 2.2.23; Copyright (C) 2020 Free Software Foundation, Inc. 3This is free software: you are free to change and redistribute it. 4There is NO WARRANTY, to the extent permitted by law. 5 6... 省略部分 ... 7 8public and secret key created and signed. 9 10pub rsa3072 2020-11-10 [SC] [expires: 2021-11-10] 11 449B75F00B2DA482AB8D03E8493DA88E2B89E19F 12uid kk70-blog (blog) <kevinz@weghst.com> 13sub rsa3072 2020-11-10 [E] [expires: 2021-11-10]
浏览证书
可以使用 gpg --list-secret-keys --keyid-format SHORT 命令查询证书列表。
1C:\Users\admin>gpg --list-secret-keys --keyid-format SHORT 2C:/Users/admin/AppData/Roaming/gnupg/pubring.kbx 3------------------------------------------------ 4sec rsa3072/2B89E19F 2020-11-10 [SC] [expires: 2021-11-10] 5 449B75F00B2DA482AB8D03E8493DA88E2B89E19F 6uid [ultimate] kk70-blog (blog) <kevinz@weghst.com> 7ssb rsa3072/6B7BF2DA 2020-11-10 [E] [expires: 2021-11-10]
发布证书
gpg --keyserver hkps.pool.sks-keyservers.net --send-keys 2B89E19F
使用 gpg 命令将证书发布到公共服务器 2B89E19F 替换为自己证书的 keyid。可在 http://keys.gnupg.net/ 网站搜索自己发布的证书。
Gradle 项目配置
配置 Gradle 插件
1plugins { 2 id "maven-publish" 3 id "signing" 4}
要使用 Gradle 发布依赖至 Maven 仓库你至少需要 maven-publish 插件。如果需要发布依赖至 Maven 中央仓库还需要使用 signing 插件对依赖文件进行签名验证。
Gradle Publish 配置
1ext { 2 isReleasedVersion = !project.version.endsWith("-SNAPSHOT") 3} 4 5publishing { 6 publications { 7 mavenJava(MavenPublication) { 8 from components.java 9 artifact sourcesJar 10 artifact javadocJar 11 12 pom { 13 description = "Yein Chaos Core" 14 scm { 15 connection = "scm:git:git@github.com:kevin70/chaos.git" 16 developerConnection = "scm:git:ssh://github.com/kevin70/chaos.git" 17 url = "https://github.com/kevin70/chaos" 18 } 19 } 20 } 21 } 22 23 repositories { 24 maven { 25 credentials { 26 username findProperty("ossrhUsername") ?: System.getenv("OSSRH_USERNAME") 27 password findProperty("ossrhPassword") ?: System.getenv("OSSRH_PASSWORD") 28 } 29 30 if (!isReleasedVersion) { 31 url "https://oss.sonatype.org/content/repositories/snapshots" 32 } else { 33 url "https://oss.sonatype.org/service/local/staging/deploy/maven2" 34 } 35 } 36 } 37}
isReleasedVersion将快照版本与正式版本分开提交至不同的 Maven 仓库;publishing.publications.mavenJava需要同步的依赖资源;artifact sourcesJar需要发布的源码 jar 包;artifact javadocJar需要发布的 javadoc jar 包;pom自定义pom.xml文件内容。
publishing.repositories发布的仓库配置;maven.credentialsMaven 仓库的认证信息;maven.urlMaven 仓库的 URL。
Gradle Singing 配置
1signing { 2 sign publishing.publications.mavenJava 3}
将需要发布的内容签名 https://docs.gradle.org/current/userguide/signing_plugin.html。
这里默认采用 Signatory credentials 签名认证方式。
Github Actions 配置
首先在 GitHub Project > Settings > Secrets 中配置一些必要的参数。

以上的所有参数后面都会在 GitHub Workflow 中使用到。
OSSRH_USERNAME是 sonatype 的登录用户名;OSSRH_PASSWORD是 sonatype 的登录密码;SIGNING_KEY_ID是 GPG 证书的 ID;SIGNING_SECRET_KEY_RING_FILE是 GPG 证书的的秘钥采用 BASE64 编码。
获取 SIGNING_KEY_ID
使用 gpg --list-secret-keys --keyid-format SHORT 命令获取 SIGNING_KEY_ID。
1$ gpg --list-secret-keys --keyid-format SHORT 2 3C:\Users\admin>gpg --list-secret-keys --keyid-format SHORT 4C:/Users/admin/AppData/Roaming/gnupg/pubring.kbx 5------------------------------------------------ 6sec rsa3072/2B89E19F 2020-11-10 [SC] [expires: 2021-11-10] 7 449B75F00B2DA482AB8D03E8493DA88E2B89E19F 8uid [ultimate] kk70-blog (blog) <kevinz@weghst.com> 9ssb rsa3072/6B7BF2DA 2020-11-10 [E] [expires: 2021-11-10]
其中 2B89E19F 为 SIGNING_KEY_ID。
获取 SIGNING_SECRET_KEY_RING_FILE
将秘钥导出至文件 secring.gpg。
$ gpg --export-secret-keys 2B89E19F > secring.gpg
将秘钥文件是二进制的我们需要将内容编码为 BASE64。因为我使用的 Windows 所以下面这个命令我是在 Git Bash 中运行的,如果你使用的 Mac 或 Linux 也可以直接运行如下的命令。
$ base64 secring.gpg > secring.gpg.b64
将编码好的文件 secring.gpg.b64 中的内容设置在 Secrets 中。
⚠️ 因为我生成的证书未设置密码,所以这里缺少了
passphrase配置,如果你的证书是有设置密码的需要额外增加passphrase的配置。
GitHub Secrets 设置完成,接下来编写 GitHub Action Workflow。
GitHub Action Workflow
1name: Chaos CI with Gradle 2 3on: 4 push: 5 branches: [ main ] 6 pull_request: 7 branches: [ main ] 8 9jobs: 10 build: 11 runs-on: ubuntu-latest 12 steps: 13 - uses: actions/checkout@v2 14 # 运行 JDK 配置 15 - name: Set up JDK 11 16 uses: actions/setup-java@v1 17 with: 18 java-version: 11 19 20 # Gradle 缓存配置 21 - name: Cache Gradle packages 22 uses: actions/cache@v2 23 with: 24 path: ~/.gradle/caches 25 key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 26 restore-keys: ${{ runner.os }}-gradle 27 28 # 给 gradlew 文件授权 29 - name: Grant execute permission for gradlew 30 run: chmod +x gradlew 31 32 # 构建项目 33 - name: Build with Gradle 34 run: ./gradlew build 35 36 # 将秘钥解码后将文件放置 ~/.gradle/secring.gpg 37 - name: Decode 38 run: | 39 echo "${{secrets.SIGNING_SECRET_KEY_RING_FILE}}" > ~/.gradle/secring.gpg.b64 40 base64 -d ~/.gradle/secring.gpg.b64 > ~/.gradle/secring.gpg 41 42 # 发布项目 43 - name: Publish 44 run: ./gradlew publish -Psigning.keyId=${{secrets.SIGNING_KEY_ID}} -Psigning.password= -Psigning.secretKeyRingFile=$(echo ~/.gradle/secring.gpg) 45 env: 46 OSSRH_USERNAME: ${{secrets.OSSRH_USERNAME}} 47 OSSRH_PASSWORD: ${{secrets.OSSRH_PASSWORD}}
当任务运行完成之后上 Maven 仓库中确认是否已经发布成功。