原文地址:https://alphahinex.github.io/2020/01/17/github-packages-in-action/
GitHub Packages 可以用來當做 Release 版本 jar 包的 Maven 倉庫。
與 Maven 中央庫比,沒有繁瑣的申請流程,可以快速的將 jar 包發布出去供他人使用。
與 Nexus 私服相比,無需架設公網訪問環境。
缺點 是只支持 Release 版本的發布和下載,Snapshot 版本雖然可以發布上去,但無法被其他項目依賴。目前尚不支持自行刪除已上傳的 jar 包,需聯系 GitHub 協助處理。
本文以實例說明,在 Gradle 中如何利用 GPR(GitHub Packages Registry)進行發布版 jar 包的上傳、下載及刪除。
上傳
參考 官方文檔,需完成如下步驟。
在 GitHub 創建 Personal access token
GPR 相當于一個需要權限才可訪問的 Maven 倉庫。故必須使用 GitHub 賬號進行相應操作。雖按文檔描述可直接利用 GitHub 賬號密碼(實際若直接用密碼,會收到提示,無法正常使用),但更推薦的是通過 token 的方式,限定 token 的權限范圍,利用不同 token 完成不同操作。
可在 https://github.com/settings/tokens 創建個人的 token,GRP 相關權限可見 About tokens。
建議創建如下兩個 token:
- 只讀 token(包含
read:packages
):可用來從 GPR 下載自己 及他人 發布的 jar 包 - 管理 token(包含
read:packages
,write:packages
,delete:packages
,repo
):可發布、刪除 packages
在 build.gradle
中添加配置
借助 Gradle 的 maven-publish
插件,將 GPR 配置為 Maven 倉庫,通過 publish
task 即可完成上傳。
以使用 Gradle Groovy 的單包倉庫為例,可在 build.gradle
中添加如下內容(注意替換 username
和 password
):
plugins {
id("maven-publish")
}
publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/OWNER/REPOSITORY")
credentials {
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") ?: System.getenv("PASSWORD")
}
}
}
publications {
gpr(MavenPublication) {
from(components.java)
}
}
}
更多示例可參考 官方文檔 或 spring-roll 項目的 實例。
此處需補充一下,發布 jar 包時若需要包含源碼,需在編譯階段生成好源碼 jar 包。
Gradle 6.0.1 Java 插件對此提供了支持,可直接在 build.gradle
中添加如下內容
java {
withSourcesJar()
}
若是 6.x 之前的版本,可自定義 task 完成源碼 jar 包的打包,但是否能正常上傳 GPR 未驗證。
發布
$ ./gradlew publish
發布成功后,可在倉庫的 packages 選項卡或 Profile 中查看,也可使用類似 https://maven.pkg.github.com/alphahinex/spring-roll/io/github/spring-roll/roll-base/0.0.1.RELEASE/roll-base-0.0.1.RELEASE.pom 的地址(需提供 GPR 的訪問權限)確認。
開發時若需要將 SNAPSHOT 版本發布到本地 Maven 庫,可使用
./gradlew publishToMavenLocal
,并在項目build.gradle
文件的repositories
塊中增加mavenLocal()
。
下載
需下載他人發布到 GPR 中的 jar 包時,配置方式與配置 Nexus 私服的方式類似,例如:
repositories {
mavenCentral()
mavenLocal()
maven {
url "https://maven.pkg.github.com/alphahinex/spring-roll"
credentials {
username = 'GITHUB_USERNAME'
password = 'TOKEN_WITH_READ:PACKAGES_SCOPE'
}
}
}
之后在 dependencies
中添加依賴,如 implementation 'io.github.spring-roll:roll-base:0.0.1.RELEASE'
,若一切順利即可下載到 roll-base v0.0.1.RELEASE 的 jar 包和源碼。
刪除
雖然有 delete:packages
權限,但目前 GitHub 僅允許用戶對上傳到 GPR 的私有倉庫的 jar 包進行刪除。
若需要刪除公開倉庫的 jar 包,需通過 支持 與 GitHub 聯系,并提供需要刪除的包的鏈接。
刪除私有庫的 jar 包需使用 GitHub 在 GraphQL 中提供的刪除方法(未驗證)。
刪除前需獲得要刪除的包的 packageVersionId
(界面不可見),可通過查詢接口進行查詢,如:
$ curl -X POST \
-H "Authorization: bearer TOKEN" \
-H "Accept: application/vnd.github.packages-preview+json" \
-d '{"query": "query { user(login: \"AlphaHinex\") { registryPackagesForQuery(packageType: MAVEN, first: 100) { edges { node { name id version(version: \"0.1.0.RELEASE\") { id version }} } } }}"}' https://api.github.com/graphql
得到類似下方的信息:
{
"data": {
"user": {
"registryPackagesForQuery": {
"edges": [
{
"node": {
"name": "io.github.spring-roll.roll-base",
"id": "MDc6UGFja2FnZTkyOTgy",
"version": {
"id": "MDE0OlBhY2thZ2VWZXJzaW9uNTI3MTcx",
"version": "0.1.0-SNAPSHOT"
}
}
},
{
"node": {
"name": "io.github.spring-roll.roll-dev-configs",
"id": "MDc6UGFja2FnZTkyOTg0",
"version": {
"id": "MDE0OlBhY2thZ2VWZXJzaW9uNTI3MTcy",
"version": "0.1.0-SNAPSHOT"
}
}
},
{
"node": {
"name": "io.github.spring-roll.roll-dl",
"id": "MDc6UGFja2FnZTkyOTg1",
"version": {
"id": "MDE0OlBhY2thZ2VWZXJzaW9uNTI3MTcz",
"version": "0.1.0-SNAPSHOT"
}
}
},
{
"node": {
"name": "io.github.spring-roll.roll-test",
"id": "MDc6UGFja2FnZTkyOTg2",
"version": {
"id": "MDE0OlBhY2thZ2VWZXJzaW9uNTI3MTc0",
"version": "0.1.0-SNAPSHOT"
}
}
},
{
"node": {
"name": "io.github.spring-roll.roll-utils",
"id": "MDc6UGFja2FnZTkyOTg3",
"version": {
"id": "MDE0OlBhY2thZ2VWZXJzaW9uNTI3MTc3",
"version": "0.1.0-SNAPSHOT"
}
}
},
{
"node": {
"name": "io.github.spring-roll.roll-web",
"id": "MDc6UGFja2FnZTkyOTg4",
"version": {
"id": "MDE0OlBhY2thZ2VWZXJzaW9uNTI3MTc5",
"version": "0.1.0-SNAPSHOT"
}
}
}
]
}
}
}
}
獲得到要刪除的 jar 包的 packageVersionId
后,依舊通過 GraphQL 接口刪除:
$ curl -X POST \
-H "Accept: application/vnd.github.package-deletes-preview+json" \
-H "Authorization: bearer TOKEN" \
-d '{"query":"mutation { deletePackageVersion(input:{packageVersionId:\"MDc6UGFja2FnZTkyOTgy\"}) { success }}"}' \
https://api.github.com/graphql
實例
- jar 包發布可參考項目 spring-roll
- 使用 jar 包可參考項目 seata-at-demo