快速發佈組件到mavenCentral

前言

在好久以前寫過一篇發佈開源庫到jcenter的文章,但不幸的是幾個月前Jfrog發佈了終止Bintray服務的聲明,聲明的大概意思是說2021年3月31號以後Jcenter倉庫將再也不接收用戶的組件提交,同時將Jcenter設爲只讀代碼倉庫,無限期地提供現有組件供用戶下載,也就是說目前Jcenter倉庫的狀態是你沒法再提交組件的更新,但你能夠繼續下載你之前託管的組件版本,因此如今你要作的就是把你的組件的新版本發佈到其餘倉庫,例如Jitpack和MavenCentral,我曾經寫過一篇快速發佈開源庫到jitpack的文章,本篇文章的內容是教你如何發佈組件到MavenCentral倉庫,同時寫了一個發佈腳本簡化發佈過程,使用這個腳本以前先看一下本篇文章的前期準備內容。html

腳本地址:MavenPublishScriptjava

前期準備

在講解以前,有必要介紹一下Sonatype 、OSSRH、MavenCentral之間的關係,Sonatype是一間公司,它運營着MavenCentral倉庫,咱們想要發佈組件到MavenCentral,必需要經過Sonatype的OSSRH,OSSRH即OSS Repository Hosting,對象存儲倉庫託管,Sonatype使用Nexus Repository Manager爲組件提供存儲庫託管服務,咱們發佈組件時要先發布到Sonatype OSSRH上,而後才能同步到MavenCentral倉庫,就好像咱們以前使用Jcenter時,要先發布到Jfrog Bintray上,而後才能同步到Jcenter倉庫。android

一、註冊Sonatype帳號

首先你須要註冊一個Sonatype Jira帳號,Sonatype使用Jira管理你的groupId申請過程,註冊地址以下:git

Sonatype Jira - Sign upgithub

點開註冊地址後,如圖:redis

mavencentral1.png

按要求填入你的郵箱地址、姓名、用戶名、密碼便可,其中用戶名最好不要有中文,記住你的用戶名和密碼,會在後面用到。算法

二、申請groupId

咱們平時使用託管在遠程倉庫的組件時都是經過它的GAV座標來定位的,GAV即groupId、artifactId、version,其中groupId你能夠理解爲你本身在Sonatype OSSRH建立的倉庫,groupId就是你倉庫的名稱,申請groupId就是在Sonatype OSSRH申請建立屬於你的倉庫,咱們後面發佈組件時要先發布到Sonatype OSSRH上名爲groupId的倉庫,而後才能同步到MavenCentral倉庫。apache

還有申請的groupId並非順便填的,按照Sonatype的要求,groupId必需要是一個域名的反寫,因此你要擁有一個域名,當你申請groupId時,Sonatype會用某種方式讓你證實你是這個域名的全部者。ubuntu

若是你擁有某個域名,例如example.com域名,你可使用任何以com.example開頭的groupId,例如com.example.test一、com.example.test2等,若是你沒有本身的域名也不要緊,Sonatype支持代碼託管平臺的Pages網站域名,例如Github,你能夠在你的Github帳號上開啓你的Pages服務,這樣你就擁有了一個與Github帳號關聯的我的域名,格式爲{username}.github.io,例如個人Github Pages網站就是rain9155.github.io,不少人都是利用這種託管在三方平臺的網站搭建本身的博客網站,除了Github,Sonatype還支持GitLab、Gitee等,下面表格列出這些經常使用的代碼託管平臺Pages服務開啓的官方教程地址,和開啓後對應的域名和相應的groupId:bash

代碼託管平臺 Pages服務開啓教程地址 域名 groupId
Github pages.github.com/ {username}.github.io io.github.{username}
Gitee gitee.com/help/articl… {username}.gitee.io io.gitee.{username}
GitLab about.gitlab.com/stages-devo… {username}.gitlab.io io.gitlab.{username}

下面就以個人Github Pages網站域名rain9155.github.io爲例,申請名爲io.github.rain9155的groupId,首先打開Sonatype Jira網站, 地址以下:

Sonatype Jira - Dashboard

首次進入須要你登錄,輸入你剛纔註冊的Sonatype Jira用戶名和密碼登錄,而後就進入Sonatype Jira網站首頁,而後點擊導航欄的Create按鈕,此時會彈出一個彈窗,會讓你填一些申請groupId時須要的信息,其中Project選擇Community Support - Open Source Project Repository Hosting (OSSRH),Issue Type選擇New Project,Summary填一個標題,Group Id就填你要申請的groupId,Project URL隨便填一個你的組件倉庫地址,SCM url也是隨便填一個你的組件倉庫版本控制地址,以下:

mavencentral2.png

最後點擊create按鈕,它會建立一個issue,issue名稱格式爲OSSRH-{taskId},如我這裏爲OSSRH-69596,你能夠在All Projects面板中看到它,而後接下來就是等待Sonatype Jira的郵件通知,郵件會發送到你註冊帳號時填寫的郵箱,它的第一封郵件會叫你在你的Github中建立一個名爲OSSRH-{taskId}的空倉庫,從而證實你是groupId對應域名的擁有者,當你建立以後,你須要到OSSRH-{taskId}下的comment面板中回覆,當你回覆後,它又會再發一封郵件給你,告訴你groupId已經申請完畢,此時你能夠發佈組件到Sonatype OSSRH中,如何發佈請看後面的內容,當你發佈後,你須要在Sonatype OSSRH中把你的組件同步到MavenCentral後才能夠經過GAV引用它,如何同步請看後面的內容,當你同步後,你須要再次到OSSRH-{taskId}下的comment面板中回覆,而後Sonatype OSSRH纔會爲你激活組件同步到MavenCentral的程序,整個交流過程能夠參考我OSSRH-69596中的comment面板,以下:

mavencentral3.png

回覆的內容是什麼不重要,只要你回覆了就行,上述就是申請groupId和激活MavenCentral同步的整個流程,只須要在第一次發佈組件時進行一次就行,之後發佈組件時不須要再進行上面的過程,直接使用該groupId就行。

三、生成gpg簽名信息

Sonatype要求發佈到MavenCentral倉庫的組件中的每一個文件都須要經過gpg簽名,gpg是一個命令行工具,提供了對數據的簽名和加密能力,支持主流的簽名和加密算法,並提供了密鑰管理系統,要使用gpg簽名,咱們必須先在電腦上安裝gpg,而後使用gpg生成簽名須要的密鑰對。

咱們首先來安裝gpg,對於mac電腦,直接經過Homebrew安裝就行,在命令行執行:

$ brew install gpg
複製代碼

對於window電腦,咱們能夠下載gpg的執行文件安裝,下載地址以下:

gpg download

安裝完成後,在命令行輸入gpg --version 輸出gpg的版本信息表示安裝完成,以下:

$ gpg --version
gpg (GnuPG) 2.2.27
libgcrypt 1.8.7
Copyright (C) 2021 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: C:/Users/HY/AppData/Roaming/gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
複製代碼

而後在命令行輸入gpg --full-generate-key 進行密鑰對生成,這個命令會讓你一步步選擇生成密鑰對須要的信息,以下:

$ gpg --full-generate-key
gpg (GnuPG) 2.2.27; Copyright (C) 2021 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072)
Requested keysize is 3072 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: rain9155
Email address: jianyu9155@gmail.com
Comment:
You selected this USER-ID:
    "rain9155 <jianyu9155@gmail.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key DF7B4B4D1A32FB02 marked as ultimately trusted
gpg: revocation certificate stored as 'C:/Users/HY/AppData/Roaming/gnupg/openpgp-revocs.d\9E02D0E104E3D3517B5B0E54DF7B4B4D1A32FB02.rev'
public and secret key created and signed.

Note that this key cannot be used for encryption.  You may want to use
the command "--edit-key" to generate a subkey for this purpose.
pub   rsa3072 2021-07-06 [SC]
      9E02D0E104E3D3517B5B0E54DF7B4B4D1A32FB02
uid                      rain9155 <jianyu9155@gmail.com>
複製代碼

首先它會讓你選擇算法,我這裏選擇了RSA,僅用於簽名,而後會讓你輸入密鑰長度,默認是3072bits,而後會讓你選擇密鑰的過時時間,我這裏選擇了永久有效,建議你們也選擇永久有效,而後確認信息後會讓你輸入姓名、郵箱、註釋來做爲密鑰的惟一標識,這裏我生成的標識爲"rain9155 <jianyu9155@gmail.com>",最後確認後會彈出一個彈窗讓你輸入一個密碼來保護你的私鑰,記住你輸入的密碼後面會用到,點擊確認後看到public and secret key created and signed這句話說明密鑰對生成完畢,咱們能夠經過gpg --list-keys列出生成的公鑰信息,經過gpg --list-secret-keys列出生成的私鑰信息,但其實列出的信息是相似的,咱們以gpg --list-keys爲例,以下:

$ gpg --list-keys
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
C:/Users/HY/AppData/Roaming/gnupg/pubring.kbx
---------------------------------------------
pub   rsa3072 2021-07-06 [SC]
      9E02D0E104E3D3517B5B0E54DF7B4B4D1A32FB02
uid           [ultimate] rain9155 <jianyu9155@gmail.com>
複製代碼

列出的信息首先有公鑰的文件位置,這裏爲C:/Users/HY/AppData/Roaming/gnupg/pubring.kbx,接着是pub rsa3072 2021-07-06 [SC],表示使用RSA算法,公鑰長度爲3072bits,建立日期爲2021-07-06,接着是長長的一串id值9E02D0E104E3D3517B5B0E54DF7B4B4D1A32FB02,它表示公鑰的id,咱們使用時只須要用到它的後八位就行,因此咱們後面使用這個公鑰時只須要使用1A32FB02就行,最後是公鑰的惟一標識uid,根據咱們前面輸入的姓名、郵箱、註釋生成。

咱們簽名只須要用到私鑰,而公鑰須要上傳到公鑰服務器,這樣咱們用私鑰簽名的文件上傳到MavenCenral後,它才能使用公鑰驗證這個文件,這裏我選擇了keyserver.ubuntu.com這個公鑰服務器,上傳公鑰的命令格式爲gpg --keyserver 公鑰服務器地址 --send-keys 公鑰id,以下我把剛剛生成的公鑰1A32FB02上傳到公鑰服務器:

$ gpg --keyserver keyserver.ubuntu.com --send-keys 1A32FB02
gpg: sending key DF7B4B4D1A32FB02 to hkp://keyserver.ubuntu.com
複製代碼

沒有錯誤提示就表示上傳成功,咱們還可使用gpg --keyserver 公鑰服務器地址 --recv-keys 公鑰id從公鑰服務器導入公鑰到本地從而驗證公鑰是否上傳成功,以下:

$ gpg --keyserver keyserver.ubuntu.com --recv-keys 1A32FB02
gpg: key DF7B4B4D1A32FB02: "rain9155 <jianyu9155@gmail.com>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1
複製代碼

能夠看到導入成功,表示公鑰已經成功上傳到公鑰服務器。

還有最後一步,把私鑰導出到一個文件中,這樣咱們發佈組件時才能經過引用這個文件,從而使用私鑰進行簽名,命令格式爲gpg -o 導出的文件路徑 --export-secret-key 私鑰id,執行導出私鑰命令會彈出一個彈窗讓你輸入私鑰密碼,輸入正確後才能成功導出,以下把私鑰導出到名爲1A32FB02.gpg的文件中,私鑰id和公鑰id是同樣的:

$ gpg -o D:/File/keystore/1A32FB02.gpg --export-secret-key 1A32FB02
複製代碼

如今已經成功把私鑰導出D:/File/keystore/1A32FB02.gpg中,記住你導出的私鑰文件路徑,後面會用到。

發佈到OSSRH

如今萬事俱備,能夠發佈組件了,發佈組件使用maven-publish插件,咱們主要發佈的內容有組件的aar或jar文件、sources文件、javadoc文件,pom文件,還有這些文件的簽名文件,以.asc爲後綴,簽名要使用signing插件,爲了簡化發佈過程,我已經把發佈過程編寫成了一個gradle腳本 - MavenPublishScript,使用時只須要apply進來,而後填寫發佈的基本信息,執行發佈任務就能夠自動生成發佈所需的全部文件併發布到OSSRH中,下面簡單介紹如何使用這個gradle腳本。

首先在你的組件的build.gradle中apply該腳本:

apply from: 'https://raw.githubusercontent.com/rain9155/MavenPublishScript/main/script/publication.gradle'
複製代碼

接下來準備好你在前面註冊的Sonatype帳號、申請好的groupId、生成好的gpg私鑰信息,而後在組件的gradle.properties(沒有則建立)中添加組件信息,其中GAV座標是必填信息,其餘是可選信息:

### GAV座標
publish.groupId=io.github.rain9155
publish.artifactId=mavenpublishscript
publish.version=1.0.0

### 下面都是可選信息
# 基本描述
publish.description=發佈組件到Maven倉庫的gradle腳本,支持aar和jar發佈
publish.url=https://github.com/rain9155/MavenPublishScript
# 開發者信息
publish.developerName=rain9155
publish.developerEmail=jianyu9155@gmail.com
# license信息
publish.licenseName=The Apache License, Version 2.0
publish.licenseUrl=http://www.apache.org/licenses/LICENSE-2.0.txt
# scm信息,格式參考http://maven.apache.org/scm/scm-url-format.html
publish.scmUrl=https://github.com/rain9155/MavenPublishScript/tree/master
publish.scmConnection=scm:git:git://github.com/rain9155/MavenPublishScript.git
publish.scmDeveloperConnection=scm:git:ssh://github.com:rain9155/MavenPublishScript.git
# 若是發佈的是android組件,當爲false時不根據flavor動態生成組件的artifactId,若是你不想組件的artifactId拼接flavorName,能夠設置爲false,默認爲true
publish.artifactId.isAppendFavorName=false
複製代碼

而後在項目根目錄的local.properties(沒有則建立)中添加gpg簽名信息和ossrh帳號信息,記得要把local.properties從你的版本控制中移除,避免泄漏你的簽名信息和帳號信息:

# gpg簽名信息
signing.keyId=你的密鑰id,例如1A32FB02
signing.password=你的私鑰密碼
signing.secretKeyRingFile=你的私鑰文件路徑,例如D:/File/keystore/1A32FB02.gpg

# ossrh帳號信息
ossrh.username=你的ossrh帳號名,即Sonatype帳號用戶名
ossrh.password=你的ossrh帳號密碼,即Sonatype帳號密碼
複製代碼

最後在命令行執行gradle任務發佈組件,若是你發佈的是android組件(aar),執行的任務的名稱格式爲publish{flavorName}AndroidlibPublicationToMavenRepositorypublish{flavorName}AndroidlibPublicationToMavenLocal,其中flavorName爲android組件的flavor的名稱,首字母大寫,沒有則不填flavorName,若是你發佈的是java組件(jar),執行的任務名稱爲publishJavalibPublicationToMavenRepositorypublishJavalibPublicationToMavenLocal

//發佈android組件到maven本地倉庫
gradle publishAndroidlibPublicationToMavenLocal

//發佈android組件到maven遠程release或snapshot倉庫
gradle publishAndroidlibPublicationToMavenRepository

//假設android組件含有flavorName爲china,發佈china版本的android組件到maven本地倉庫
gradle publishChinaAndroidlibPublicationToMavenLocal

//假設android組件含有flavorName爲oversea,發佈oversea版本的android組件到maven遠程release或snapshot倉庫
gradle publishOverseaAndroidlibPublicationToMavenRepository

//發佈java組件到maven本地倉庫
gradle publishJavalibPublicationToMavenLocal

//發佈java組件到maven遠程release或snapshot倉庫
gradle publishJavalibPublicationToMavenRepository

//發佈全部android組件和java組件到maven本地倉庫
gradle publishToMavenLocal

//發佈全部android組件和java組件到maven遠程release或snapshot倉庫
gradle publishAllPublicationsToMavenRepository

//發佈全部android組件和java組件到maven本地倉庫和maven遠程release或snapshot倉庫
gradle publish
複製代碼

上述發佈任務根據組件發佈的是android組件(aar)仍是java組件(jar)來執行,同時發佈android組件時支持flavor發佈,publishXXToMavenRepository任務表示發佈到遠程倉庫OSSRH中,publishXXToMavenLocal任務表示發佈到maven本地倉庫,maven本地倉庫路徑爲{用戶目錄}/.m2/repository/,也能夠在AS左側的gradle面板中查看這些任務,以下:

mavencentral4.png

選中合適的任務雙擊執行就行,若是你執行的是publishXXToMavenRepository任務,任務執行成功後你就能夠到OSSRH查看你發佈上去的組件,首次進入須要登錄,輸入你的Sonatype用戶名和密碼登錄,而後點擊左下側的Staging Repository就能夠看到你發佈到OSSRH的組件,以下:

mavencentral5.png

在Staging Repository的面板中能夠瀏覽你發佈的組件,選中它,而後點擊下面的content面板就能夠查看組件發佈的詳細文件。

同步到MavenCentral

組件發佈到OSSRH後,還不能經過GAV引用它,還要同步到MavenCentral後才能經過GAV引用它,首先要在OSSRH上Close組件,讓它從open狀態變爲close狀態,以下:

mavencentral6.png

當你點擊Close按鈕後,會彈出一個彈窗叫你確認,確認後Close按鈕會變灰,此時下方的Activity面板會顯示close過程當中進行的規則校驗,例如校驗你發佈的文件是否有簽名、是否含有javadoc文件、是否含有sources文件,pom文件是否合格等,當全部校驗經過後你才能夠同步組件到MavenCentral,當校驗經過後你會收到Sonatype發送的郵件,此時你能夠點擊上方的Release按鈕同步組件到MavenCentral,以下:

mavencentral7.png

當你點擊Release按鈕後,會彈出一個彈窗叫你確認,確認後Release按鈕會變灰,若是你是第一次發佈組件,在申請groupId時我講過,你還要到OSSRH-{taskid}的comment面板下回復它一次OSSRH纔會爲你激活同步程序,激活同步程序後大概十幾分鍾你的組件就會被同步到MavenCentral,這時你就能夠在MavenCentral網站搜索到你的組件,並能夠在gradle或maven等構建工具中經過GAV引用它,激活同步程序後,你下次Release組件時就會自動同步到MavenCentral而無需再作其餘操做。

結語

發佈到MavenCentral的步驟相比於發佈到Jitpack要複雜的多,Jitpack只須要一個代碼託管倉庫帳號,而MavenCentral須要準備Sonatype帳號、我的域名、簽名信息,可是MavenCentral比Jitpack成熟得多,它目前是最大的java組件和其餘開源組件的託管倉庫,也是不少構建系統如Maven的默認存儲倉庫,如何選擇就看我的愛好了。

以上就是本文的全部內容!

參考資料:

JCenter service update

The Central Repository Documentation

Use the Maven Publish plugin

相關文章
相關標籤/搜索