如何通过GitHub Actions将Maven项目部署到GitHub Packages?
我有一个存储已编译Maven项目的GitHub仓库,已配置GitHub Actions将其部署到GitHub Packages,但卡在凭证配置环节,且希望避免使用个人账号凭证。
当前配置
初始Workflow文件 release-package.yml
name: Maven Package on: push jobs: publish-gpr: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: '3.10' - uses: actions/setup.java@v3 with: java-version: '11' distribution: 'adopt' server-id: github server-username: ... server-password: ... - name: Publish Package run: | chmod +x ./deploy.sh ./deploy.sh shell: bash
核心问题是server-username和server-password的取值,不想使用个人账号凭证。
部署脚本 deploy.sh
#!/bin/bash OWNER=... REPOSITORY=... filelist=$(find . -type f -path "*.pom") for file in $filelist do data=$(python getdata.py $file) groupId=$(echo $data | cut -d' ' -f1) artifactId=$(echo $data | cut -d' ' -f2) version=$(echo $data | cut -d' ' -f3) mvn deploy:deploy-file -DgroupId=$groupId -DartifactId=$artifactId -Dversion=$version -Dfile=$file -Durl=https://maven.pkg.github.com/$OWNER/$REPOSITORY done
其中OWNER和REPOSITORY未填写。
尝试过的方案及错误
曾尝试使用Actions Secrets或Deploy Keys,但配置后均出现401 Unauthorized错误。也试过更新Workflow并传入GITHUB_TOKEN:
name: Maven Package on: push jobs: publish-gpr: runs-on: ubuntu-latest permissions: contents: read deployments: write packages: write steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: '3.10' - uses: actions/setup.java@v3 with: java-version: '11' distribution: 'adopt' - name: Publish Package run: | chmod +x ./deploy.sh ./deploy.sh shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
但仍收到错误:
Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy-file (default-cli) on project standalone-pom: Failed to deploy artifacts: Could not transfer artifact
from/to remote-repository (https://maven.pkg.github.com/ ): authentication failed for https://maven.pkg.github.com/ / , status: 401 Unauthorized -> [Help 1]
解决方案
一、正确的凭证配置(无需个人账号)
使用GitHub Actions内置的GITHUB_TOKEN即可,它是Action运行时自动生成的临时凭证,具备当前仓库的权限,安全合规。
- Workflow中配置Maven认证
修改actions/setup-java步骤,指定认证参数:
- uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' server-id: github server-username: GITHUB_ACTOR server-password: ${{ secrets.GITHUB_TOKEN }}
这一步会自动在Maven的settings.xml中配置好GitHub Packages的服务器认证信息。
- 在deploy.sh中指定认证仓库ID
修改mvn deploy:deploy-file命令,添加-DrepositoryId=github,让Maven使用刚才配置的认证信息:
mvn deploy:deploy-file -DgroupId=$groupId -DartifactId=$artifactId -Dversion=$version -Dfile=$file -Durl=https://maven.pkg.github.com/$OWNER/$REPOSITORY -DrepositoryId=github
- 自动填充OWNER和REPOSITORY
无需手动填写,通过GitHub内置环境变量获取:
在Workflow的Publish Package步骤添加环境变量:
env: OWNER: ${{ github.repository_owner }} REPOSITORY: ${{ github.event.repository.name }}
然后deploy.sh中直接读取:
OWNER=$OWNER REPOSITORY=$REPOSITORY
二、部署方案优化建议
当前方案可行,但可以进一步简化和规范:
- 移除Python依赖
如果getdata.py仅用于解析POM的groupId、artifactId、version,改用Maven自带命令解析,无需依赖Python:
groupId=$(mvn help:evaluate -Dexpression=project.groupId -f "$file" -q -DforceStdout) artifactId=$(mvn help:evaluate -Dexpression=project.artifactId -f "$file" -q -DforceStdout) version=$(mvn help:evaluate -Dexpression=project.version -f "$file" -q -DforceStdout)
同时可以移除Workflow中的Python配置步骤。
- 限制触发条件
当前on: push会在所有推送时触发部署,建议只在主分支推送或发布标签时触发:
on: push: branches: [ main ] tags: [ v* ]
- 最小化权限
移除不必要的deployments: write权限,保留最小必要权限:
permissions: contents: read packages: write
最终优化后的完整配置
优化后的Workflow
name: Maven Package on: push: branches: [ main ] tags: [ v* ] jobs: publish-gpr: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' server-id: github server-username: GITHUB_ACTOR server-password: ${{ secrets.GITHUB_TOKEN }} - name: Publish Package run: | chmod +x ./deploy.sh ./deploy.sh shell: bash env: OWNER: ${{ github.repository_owner }} REPOSITORY: ${{ github.event.repository.name }}
优化后的deploy.sh
#!/bin/bash OWNER=$OWNER REPOSITORY=$REPOSITORY filelist=$(find . -type f -name "*.pom") for file in $filelist do groupId=$(mvn help:evaluate -Dexpression=project.groupId -f "$file" -q -DforceStdout) artifactId=$(mvn help:evaluate -Dexpression=project.artifactId -f "$file" -q -DforceStdout) version=$(mvn help:evaluate -Dexpression=project.version -f "$file" -q -DforceStdout) mvn deploy:deploy-file -DgroupId="$groupId" -DartifactId="$artifactId" -Dversion="$version" -Dfile="$file" -Durl="https://maven.pkg.github.com/$OWNER/$REPOSITORY" -DrepositoryId=github done
内容的提问来源于stack exchange,提问作者Miazite

