JitPack.io 是一個 GitHub 開源代碼庫的便捷發佈渠道。它可以讓你的 Android/Java 代碼庫自動完成發佈,從而令使用者能夠最便利地享受到你的代碼庫。
本質上說,一切能夠通過 Maven Repository 發佈的代碼庫,你都可以藉助 JitPack 的自動打包和發佈功能,從 GitHub 上發佈給大衆使用。例如你的 Kotlin/Java 代碼庫,SpringBoot 工具庫,Android 三方庫,等等,一旦你發佈了源代碼到 GitHub,並完成了提交、Release標籤動作,那麼 JitPack 上將會自動生成一個相應的符合 Maven 包引用規則的 ID:com.github.your-github-username:your-github-reponame:release-tag
。在這裏,Maven Group Name 即 com.github.your-github-username
,Maven Artifact Name 即 your-github-repo-name
。這樣的 Maven ID,三方庫使用者能夠通過 POM 或 gradle 引用到它。
那麼這和 Maven Central,JCenter 有何不同呢?最大的區別就在於你不必完成 Maven Central 的一系列註冊手續,乃至發佈一個庫之前的登記 Post 和等待管理員批准,也不必在 JCenter 上填寫冗長的標籤,找圖做圖做圖標寫說明,更不必每到發佈時做一系列的準備工作,使用專用的工具完成最後一擊。你只需要寫好你的 GitHub Repo README就行了,其他的事情,JitPack 會全數包辦。
所以很明顯,發佈一個公開的第三方庫前所未有地簡便。
當然,這一切大體上限定在 Java 及其衍生領域,例如 Android。而諸如 Python,Nodes 等就沒法
除了支持 GitHub 上的公開 Repository 的自動發佈之外,JitPack 也支持 Bucket,GitLab,Gitee 賬戶中的公開庫的發佈。
JitPack is a novel package repository for JVM and Android projects. It builds Git projects on demand and provides you with ready-to-use artifacts (jar, aar).
那麼,這裏會講講利用 JitPack.io 的方法。爲了講述方便,下面會主要使用 Android Library 作爲講解的例子。
你是庫開發者
假定你是一個Android開發者,手頭有一堆代碼行之有效,而且厭倦了每次在各個 Projects 之間拷貝來拷貝去,那麼你就建立了一個獨立的 Android Library 項目,將這些代碼打包在一起。這時,問題來了,別的工程怎麼引用這個庫呢?
Android使用一個庫,有很多種方法。
沒有 JitPack
你可以將 Library Module 嵌入到目標項目中,然後通過
dependencies {
implements ':my-library'
}
來引用它。
這很蠢,但最簡單。所以我們會將庫獨立建立一個工程 my-library
,然後通過 gradle 命令構建它,從而得到一個 .aar 文件,然後我們可以複製這個 .aar 文件到目標項目中的 app/libs/
之中,利用:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
來引用它。
這就方便多了,不過如果修訂了 my-library
的話,我們需要複製那個 .aar 到每個引用它的目標項目中,如果我們引用了5次,甚至我的團隊夥伴們引用了它時,那麼災難還是會發生。
所以我們可以用過 gradle deploy
指令將 .aar 發佈到 $HOME/.m2/repositories/
之中,然後通過 Maven Artifact ID方式引用它。如果我的團隊夥伴們也需要引用它,那麼我發佈到 Maven 私服上,就解決問題了。這時候通常是這樣的:
allprojects {
repositories {
jcenter()
google()
mavenCentral()
mavenLocal()
maven { url "https://maven.our-nexus.com" }
}
}
dependencies {
implementation 'com.example.android:my-library:1.0.1'
}
使用 JitPack
那麼新問題還是不可避免地來了,我們沒有私服呢,又或者我們的異地夥伴呢,而我們也沒有公網上的 Maven 私服呢?又或者,如果我覺得這個代碼庫具有通用性,我希望讓任何感興趣的人都能夠使用它呢?這些情況下,我們只能考慮 Maven Central,JCenter 那樣的公共 Maven Repository Servers 了,特別是針對 Android 開發的情況,JCenter 是首選的推薦。所以前文我們已經提到過了,當你的技能水平和開發經驗推進到一定水平時,你就會面臨這樣的選擇。而且你幸運的是,現在你不必要那麼麻煩了,JitPack.io 可以更好地爲你的設想進行變現。
這時候,你的 gradle 腳本中可能是像這樣子聲明引用的:
allprojects {
repositories {
jcenter()
google()
maven { url "https://jitpack.io" }
}
}
dependencies {
implementation 'com.github.Username:my-library:Tag'
}
在這裏,Username
是你的 GitHub 賬戶登錄名。而 my-library
是你的 Repository 的名字。換句話說,你的庫被放在 https://github.com/Username/m... 處可以被瀏覽器訪問。
當你的開源庫變得越來越受歡迎時,你不能使用 JitPack 方式發佈它,因爲那時候你會發現更多新的需求,你會需要更好地規劃版本推進路線圖,解決全球各地使用者的依賴、補丁修復等各類型的新問題,也爲使用者們釋疑和提供可信度,那時候你需要更嚴謹的登記自己的開源庫到 JCenter 並採取更穩定更可信賴的方式來發布代碼庫。那將會是另一篇文章了。
按照 JitPack 的官方說明,Tag
是這樣的:Tag
可以是 Release 標籤,commit hash,分支名加上 -SNAPSHOT
後綴等等。
引用 Snapshots
在開發過程中,Snapshots 版本是非常有用的。你可以這樣指定版本號來引用 repo 的 snapshots:
- commit hash
-
branch-SNAPSHOT
(替換branch
爲你的分支名)
例如:
// dependency on the latest commit in the master branch
implementation 'com.github.jitpack:gradle-simple:master-SNAPSHOT'
// dependency on the latest commit in the devel branch
implementation 'com.github.jitpack:gradle-simple:devel-SNAPSHOT'
// dependency on the certain a commit 33e0c37ee8
implementation 'com.github.jitpack:gradle-simple:33e0c37ee8'
刷新緩存
注意 Gradle 會緩存SNAPSHOT內容,所以有時候你可能無法獲取某個分支上的最新 build。Gradle 自身也提供的方法來控制這一點。你可以在 build.gradle 中要求 Gradle 總是拉取最新的 build 版本:
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
你也可以通過命令行添加 --refresh-dependencies
來要求一次 gradle build 中額外地廢除 cache 內容並從遠程拉取最新的 build 版本。Gradle documentation 提供了更多的關於控制緩存的相關信息。
使用 Android Studio 時,如果你刷新了 gradle cache,那麼你可能也需要在 AS 中通過 File -> Synchronize 菜單來更新和同步 gradle 各種依賴狀態。
對於在你的開源庫中提供多個 Modules 的情況,JitPack 也提供了相應的支持:https://jitpack.io/docs/BUILD...。不過我們並不建議你這麼去做。
引用 Release
通過 JitPack 來發布開源庫,而不是使用你的庫的 Snapshots 版本,也是超級容易的。當然,你需要具備 GitHub Release 的相關知識。
本質上說,GitHub 的 Release 和 git 的 tag 沒有什麼不同,只是在 tag 名稱上略有要求。你可以在GitHub 上通過 Web 界面建立 pre-release 和 release,但你也可以直接通過本機的命令行或者 IDE 或者 Git Client 來建立 release 標籤。無論如何,對於這些標籤的命名的這些要求,通常也符合軟件團隊的發佈策略:
git tag 0.17.2
git tag v0.17.3
git tag release-0.1.1
git tag release/v0.13.3
不同的團隊可能採取不同的 CI 策略以及 Release 命名策略。
- 較爲簡明的方式是
0.17.2
,它便於手工管理且視覺上明確無歧義。 - 採用自動化 CI 的團隊可能會使用
v0.17.3
和release/v0.13.3
,前者利用前綴觸發 CI builder Rules,而後者則在兼顧觸發規則的同時,提供一個可視化層面的更好的組織形式:當你通過多數 Git 客戶端審查代碼時,所有的 releases tags 會被組織爲release/
之下的一組節點——類似地,往往同時也會使用諸如hotfix/v0.13.3-h101
,rc/v2
,beta/1
等 tags 來組織和管理其他情形的版本。
當然,tag 的命名是全自由度的。你可以在無論是 git,git client,github,jitpack 等各種不同場合使用像 temporary-rel-1
或者 fxx-123-kk
這樣的 tag 名稱,毫無障礙地。
可以通過 Gradle 插件來幫助你管理你的 Git/GitHub 版本號:Gradle release & version management plugin
如果你尚未有任何關於如何進行 Git Tag 命名的概念的話。
一旦通過 git 命令或者任何方式建立了一個 git tag,那就代表着你建立了一個 Release,無論其名稱多麼狗屎都可以。那麼一旦你推送這個 tag 到 GitHub 之後,例如 fxx-123-kk
,任何人就可以在項目中這樣引用它:
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
dependencies {
implementation 'com.github.yourname:your-repo:fxx-123-kk'
}
這就是全部了。
發佈 JavaDoc
如果你的庫的構建腳本能夠產出 javadoc jar 包,那麼 JitPack 將會自動處理 javadoc 的生成以及發佈。你可以直接在這裏瀏覽:
-
https://jitpack.io/com/github/USER/REPO/VERSION/javadoc/
or -
https://jitpack.io/com/github/USER/REPO/latest/javadoc/
(latest release tag)
對於一個多 Module 的項目來說,它的 Maven 發佈點使用 com.github.USER.REPO:MODULE:VERSION
這樣的 Artifact。因此,相應的 JavaDoc 位置在:
https://jitpack.io/com/github/USER/REPO/MODULE/VERSION/javadoc/
Source codes jar 包會被 JitPack 自動處理,你無需額外提供處理依據或編排。
一個簡短的 Module-level build.gradle 樣本如下:
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'com.github.dcendents.android-maven'
repositories {
mavenCentral()
google()
jcenter()
maven { url "https://jitpack.io" }
}
group = 'com.github.jitpack'
version = '1.0'
android {
compileSdkVersion 28
buildToolsVersion "28.0.2"
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName version
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
androidTest.java.srcDirs += 'src/androidTest/kotlin'
androidTest.resources.srcDirs += 'src/androidTest/res'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
task sourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.sourceFiles
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
task classesJar(type: Jar) {
from "$buildDir/intermediates/classes/release"
}
artifacts {
archives classesJar
archives javadocJar
archives sourcesJar
}
其他特性
- 支持私有 Repositories。
你只需要提供一個授權給予 jitpack.io 並微調一下開發機環境就可以了,其他的部分和前文述及的用法沒有區別。具體的步驟可以參考:https://jitpack.io/private。不過,你想要通過 JitPack 發佈私有repo的話,是收費的,按月訂閱制。
- 支持動態版本號。
所以你可以使用 '1.+' 這樣的版本號。
- 可以使用自己的域名作爲groupId。
這個需要更高價位的訂閱級別。
不過對於 free 的 GitHub repo 來說,你也可以免費獲得這個特性。稍後章節我們會提到這一點。
- 一般情況下 jitpack 按照構建順序存儲你的若干個庫版本,但並不確保這些構建後的版本總是存在。就是說,直到用戶向服務器發起了拉取一個庫的請求的時候,jitpack按需就地構建請求的版本而不是提前構建好之後等待用戶發起請求。這意味着首位用戶的首次請求通常是失敗的,他需要等待構建完成後再次發佈請求時才能完成pom和庫包的下載。
通常,一個 jitpack 構建完成的版本至少會維持 7 天不變。
多數時候,我們並不真的介意有時候會拉取失敗的問題,尤其是有一次成功後本地.m2也會有一份緩存的情況。你可以登錄 JitPack.io 之後在 對應庫的構建列表中點擊 “Get It” 按鈕來明確地發出構建請求而不是由使用者發起。
自定義域名
默認時,你的庫的 groupId 爲 com.github.USER
或者 com.github.yourORGANIZATION
。但你也可以使用自己的域名前綴,例如 com.hedzr
或者 com.hedzr.lib
。爲了使用自己的域名前綴作爲 groupId,應該遵循以下的步驟:
- 添加一條 DNS TXT 記錄,以完成從 git.yourcompany.com 到 https://github.com/yourcomany。另外一種情形是:從
lib.yourdomain.com
映射到 https://github.com/USER。你需要在自己的域名託管商提供的DNS記錄修改工具中完成這樣的操作,可以參考 How to add a TXT record。 - 然後請前往 https://jitpack.io/#com.yourc... 並點擊
Look up
按鈕,確定映射已經生效。
爲了檢測TXT記錄已經生效,可以執行命令行:
dig TXT git.yourcompany.com
例如:
~$ dig txt git.jitpack.io
...
;; ANSWER SECTION:
git.jitpack.io. 600 IN TXT "https://github.com/jitpack"
支持的代碼庫網站
GitHub
GitLab
BitBucket
Gitee
角標 Badges
在你的項目的 README.md 中添加相應的角標的方法是:
[![Release](https://jitpack.io/v/User/Repo.svg)](https://jitpack.io/#User/Repo)
也可以使用非圓角的樣式:
[![Release](https://jitpack.io/v/jitpack/maven-simple.svg?style=flat-square)](https://jitpack.io/#jitpack/maven-simple)
當你使用自定義域名或者 BitBucket 時,可以這樣:
[![Release](https://jitpack.io/v/com.example/Repo.svg)](https://jitpack.io/#com.example/Repo)
[![Release](https://jitpack.io/v/org.bitbucket.User/Repo.svg)](https://jitpack.io/#org.bitbucket.User/Repo)
你是庫使用者
你需要的引用方式是在 Module-level build.gradle 中添加:
dependencies {
implementation 'com.github.Username:my-library:Tag'
}
你應該在 Top-level build.gradle 中添加 jitopack 的 Maven 倉庫:
allprojects {
repositories {
jcenter()
google()
maven { url "https://jitpack.io" }
}
}
詳細的解釋,請閱讀庫開發者
相關章節內容。
後記
關於 JitPack 的 API
這給予我們 ChatOps 回調能力或者 CI 控制能力,或者其他——取決於你的想象力。
由於 API 設計的非常簡單,因此不必另文專述。有需要者不妨直達: