JitPack.io 基本使用法

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.3release/v0.13.3,前者利用前綴觸發 CI builder Rules,而後者則在兼顧觸發規則的同時,提供一個可視化層面的更好的組織形式:當你通過多數 Git 客戶端審查代碼時,所有的 releases tags 會被組織爲 release/ 之下的一組節點——類似地,往往同時也會使用諸如 hotfix/v0.13.3-h101rc/v2beta/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,應該遵循以下的步驟:

  1. 添加一條 DNS TXT 記錄,以完成從 git.yourcompany.com 到 https://github.com/yourcomany。另外一種情形是:從 lib.yourdomain.com 映射到 https://github.com/USER。你需要在自己的域名託管商提供的DNS記錄修改工具中完成這樣的操作,可以參考 How to add a TXT record
  2. 然後請前往 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

也可以使用非圓角的樣式:

[![Release](https://jitpack.io/v/jitpack/maven-simple.svg?style=flat-square)](https://jitpack.io/#jitpack/maven-simple)

Release

當你使用自定義域名或者 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 設計的非常簡單,因此不必另文專述。有需要者不妨直達:

https://jitpack.io/docs/API/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章