1
以前在github發開源專案,都因為懶,從來不構建到中央倉庫。最近因為其他人要用,聯絡我。希望可以發到中央倉庫。我想,不就是mvn deploy嘛,開搞。一圈弄下來,發現真沒那麼簡單。當中遇到了無數的坑,讓我每一次都心裡默默唸到,發個專案,為何如此痛苦。
現將痛苦的過程詳細記錄下來。希望可以幫助到其他小夥伴少踩點坑。
首先,你需要到sonatype這個站點上去註冊一個賬號。這個頁面長這個樣子:
我當時以為我進錯地方了,這不是jira嗎。好吧。看url還是提issue的地方,這和釋出專案有毛的關係...
好吧,點新建,專案選Community Support - Open Source
,問題型別選New Project
填就是了。注意的是Group Id這裡要填你自己的擁有的域名,比如com.xxxx,沒有的話,自己去註冊域名去。填好之後就是等待稽核。我搜了下,網上小夥伴說要等待3,5天。
3個小時後,我上去再去看,管理員給我回復了:
大致意思就是要你證明這個域名是屬於你自己的。有2種方法,加一個txt型別的解析到你的域名裡是最快的方法。
我的域名申請在騰訊雲。登陸進去。找到域名解析設定。加進去txt型別的解析。主機記錄填那個jira ticket名字,記錄值是你這個ticket的連結url。
設定完了後,去回覆管理員。然後繼續等待。
管理員大概很快就回復了我。並通過了驗證。接下來,就要搗鼓專案了。
2
要上傳中央倉庫,你的專案必須要符合一些規範才行。
首先pom檔案是有要求的,在你的專案頂層pom檔案裡一定要有以下標籤:
- name
- description
- url
- licenses
- developers
- issueManagement
- scm
照著一個個填,我參考了一個開源專案的pom,例子如下:
<modelVersion>4.0.0</modelVersion>
<groupId>com.yomahub</groupId>
<artifactId>liteflow</artifactId>
<packaging>pom</packaging>
<version>2.2.0</version>
<name>liteflow</name>
<description>a lightweight and practical micro-process framework</description>
<url>https://github.com/bryan31/liteflow</url>
<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<email>weenyc31@163.com</email>
<name>bryan.zhang</name>
<url>https://github.com/bryan31</url>
<id>bryan31</id>
</developer>
</developers>
<issueManagement>
<system>Github Issue</system>
<url>https://github.com/bryan31/liteflow/issues</url>
</issueManagement>
<scm>
<connection>scm:git@github.com:bryan31/liteflow.git</connection>
<developerConnection>scm:git@github.com:bryan31/liteflow.git</developerConnection>
<url>git@github.com:bryan31/liteflow.git</url>
</scm>
補全了pom的資訊後,還需要補全一些maven外掛,主要有:
- maven-source-plugin
- maven-site-plugin
- maven-javadoc-plugin
- maven-gpg-plugin
例子如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<!-- Javadoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Gpg Signature -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
當然還需要加上distributionManagement
<distributionManagement>
<snapshotRepository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
你的sonatype的使用者名稱和密碼當然不能寫在專案pom裡,你得在maven的setting.xml
裡新增server
<server>
<id>sonatype</id>
<username>your username</username>
<password>your password</password>
</server>
3
補全了pom的一些規定資訊和外掛後。可以試下是否可以正確無誤的生成javadoc,在專案根目錄下執行
mvn site
接下去就是無盡的等待,等待從中央倉庫下載各種外掛。這裡最好搭個梯子翻牆,速度會快點。我全程用梯子,也等了40分鐘,這時候可以去幹點別的事情。。40分鐘後,終於build成功了:
接下去就是簽名了。想要上傳到倉庫,jar包必須被正確簽名。
用gpg來進行簽名,網上搜了下,windows的使用者可下載gpg4win,我這裡用的是mac,不能用這個軟體。只能自己安裝個命令列gpg工具了
brew install gpg
安裝成功後,執行命令生成祕鑰對:
gpg --gen-key
根據提示,填寫使用者名稱和郵件地址。然後確認。
我mac上用的是iterm2,確認後一直卡著,提示正在生成位元組。然後等了很久也沒有反應。我一直以為這就是正常現象,已經生成祕鑰對了。只不過命令列不友好,沒有告訴我。。。導致了我後面簽名一直籤不成功。
後來我換了一個ssh工具,electerm,才正確生成。最後是要讓你輸入passphase。以下是正確生成祕鑰對的介面
接下去就是要利用maven-gpg-plugin
對jar包進行簽名了。在進行之前,需要在setting.xml
檔案的當前profile里加上
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.passphrase>your passphrase</gpg.passphrase>
</properties>
然後執行mvn install。
我這裡一直簽名不成功,報以下錯:
網上搜尋了下,原來是我本地的gpg工具版本太新了,和maven的外掛版本不匹配。需要在~/.gnupg這個目錄下增加2個配置:
gpg.conf
use-agent
pinentry-mode loopback
gpg-agent.conf
allow-loopback-pinentry
折騰了半天,終於可以mvn install正確執行gpg的jar包簽名了。接下去準備進行激動人心的mvn deploy了。
由於之前已經解決了jar包簽名的問題,deploy過程也是相當的順利。deploy過程中,會把你專案的jar包,加簽資訊,javadoc,javasource等包一併上傳到sonatype伺服器。
deploy好,你就可以在sonatype的staging repo裡看到了,staging repo相當於暫存的狀態,還沒有正式釋出到release倉庫,sonatype需要校驗你上傳jar包的規範性,合法性。
選中你提交的暫存資訊,點close,等一段時間,refresh之後底下會有校驗結果。全部通過後才能點release。底下是我第一次校驗的結果:
可以看到,有2項沒通過,第1項是我pom不規範,原因是我第一次pom提交的時候少了<name>
標籤。關鍵是第2項簽名校驗失敗,從右邊的詳細資訊裡可以看到,sonatype在校驗我的jar包簽名時找不到我的public key。
gpg生成的是RSA的key,有公鑰和私鑰。我本地加簽之後,應該把公鑰給到sonatype,否則sonatype無法驗證我的jar包的加簽資訊是否有效。所以我之前流程應該缺少了這一步!
看詳細資訊,sonatype應該是到以下3個地方去拿key,發現都沒有,所以才報了錯。
http://pgp.mit.edu:11371
http://keyserver.ubuntu.com:11371
http://pool.sks-keyservers.net:11371
所以我們只需要上傳key到任意一個key server就可以了。
gpg上傳公鑰的命令是
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys yourkeyid
這裡我踩了2個坑,第一個是上傳的協議是hkp,不是http,網上一搜才知道。sonatype報錯的地方都是http。
第二個是gpg在傳送公鑰的時候並不是直接指定公鑰發上去,而是需要你的keyid,個人推測可能是根據這個keyid再在檔案系統中找到公鑰進行傳送吧。它需要什麼,我們只能給什麼。問題是這個keyId是什麼呢,從哪來呢
在生成祕鑰對的時候,我注意到給了一個fingerprint,也能用gpg --list-keys 這個命令進行檢視:
難道這個就是keyId?我嘗試著用這個作為keyId,進行傳送,也能成功。但是在sonatype上進行檢測卻過不了。
這個keyId卡了我很久,最後還是依靠萬能的谷歌查到了。原來所謂的KeyId就是fingerprint的後16個字元。我Fxx...(省略N個讚美的詞語)。
拿到了正確的KeyId,繼續執行gpg的上傳命令,上傳好,然後執行檢視key的命令:
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys yourkeyid
也能在key server上找到
4
我們繼續在sonatype的staging repo進行close操作校驗,這個操作其實我已經做了n遍了,各種坑,所以見到以下這個畫面的時候有點激動:
可以看到,所有的校驗都通過了,沒有報錯了。Release的按鈕也已經點亮。通往中央倉庫的大門已經敞開!
堅定的點下release按鈕。輸入備註後,成功提交。
在sonatype進行Release後 ,要真正在中央倉庫看到,可能要等上個5到6小時。
最後。終於,在中央倉庫的地址我看到了提交的包,大功告成
原本以為提交中央倉庫可能不是那麼困難,實際操作一遍,發現需要注意的細節有很多。而專案本身也有很多需要規範的地方。整個過程花了一天時間,碰了無數的坑,我工位旁邊的小夥伴之前操作過,但是時間久遠,細節又很多。所以對很多坑印象比較模糊了。所以記錄下來。
個人開發的專案被其他人所使用,是一件很有成就感的事情。所以提交中央倉庫是必然途徑。雖然我希望整個過程能簡單點,但是中央倉庫就一個,只能按照它的規範來做。希望有人看到這篇記錄,能讓你少走點彎路~
5
微信關注 「jishuyuanren」獲取更多技術乾貨