最近我做了一個開源項目 Disconf:Distributed Configuration Management Platform(分布式配置管理平台) ,簡單來說,就是為所有業務平台系統管理配置文件的平台系統。更詳細的介紹,請看項目主頁。
項目是用Java寫的,Maven管理的,那么,自然而然,整個項目應該以Maven倉庫POM方式暴露給用戶來使用。因此,這兩天我一直在折騰Maven Central Repository。
本文使用Sonatype Nexus作為代理倉庫。也就是說先要把軟件發布到這里,然后他們會幫同步到Maven的Central Repository上,這貌似是目前最簡單有效的辦法。 Sonatype使用Nexus為開源項目提供托管服務。你可以通過它發布快照(snapshot)或是穩定版(release)到Maven中央倉庫。 我們只要注冊一個Sonatype的JIRA賬號、創建一個JIRA ticket,然后對POM文件稍作配置即可。
Disconf的項目結構介紹
disconf
- disconf-client
- disconf-core
- disconf-web
- disconf-demos
我將會把 disconf-core和disconf-client 推送到Maven的Central Repository上,因為這兩個包是編程用戶需要的。disconf-web 的編譯結果是一個war包,因此不會推送到Maven的Central Repository上。
下面將仔細的介紹 disconf-core 包的推送過程。
第零步:將你的電腦與Github打通
用ssh-key生成的id_rsa.pub的內容放到 https://github.com/settings/ssh 中。
第一步:修改 disconf-core 的 POM文件
它至少應該包括以下標簽:
具體可參見:https://github.com/knightliao/disconf/blob/master/disconf-core/pom.xml
<modelVersion>4.0.0</modelVersion>
<artifactId>disconf-core</artifactId>
<packaging>jar</packaging>
<version>2.3-SNAPSHOT</version>
<name>disconf-core</name>
<parent>
<groupId>com.baidu.disconf</groupId>
<artifactId>disconf-base</artifactId>
<version>2.1</version>
<relativePath>../</relativePath>
</parent>
<url>https://github.com/knightliao/disconf/tree/master/disconf-core</url>
<description>https://github.com/knightliao/disconf/tree/master/disconf-core</description>
<organization>
<name>Baidu</name>
<url>http://www.baidu.com</url>
</organization>
<scm>
<url>scm:git:git@github.com:knightliao/disconf</url>
<connection>scm:git:git@github.com:knightliao/disconf</connection>
<tag>disconf-core</tag>
</scm>
下面為它設置一個profile, 命名為release,意思就是發布到中央庫。這里設置了兩個庫,一個snapshots,一個是正式的發布庫。
另外,中央庫需要source和doc,所以增加兩個plugin.
<profiles>
<profile>
<id>release</id>
<distributionManagement>
<snapshotRepository>
<id>nexus-release</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>nexus-release</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<build>
<plugins>
<!-- Source -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Javadoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
第二步:修改 disconf 的 POM文件
disconf的Pom是disconf-core的parent pom。
具體可參見:https://github.com/knightliao/disconf/blob/master/pom.xml
它至少應該包括以下標簽:
<developers>
<developer>
<name>Liao Qiqi</name>
<id>knightliao</id>
<email>liaoqiqi (AT) baidu.com</email>
<roles>
<role>Developer</role>
</roles>
<timezone>+8</timezone>
</developer>
<developer>
<name>Wu Ning</name>
<id>wuning</id>
<email>wuning01 (AT) baidu.com</email>
<roles>
<role>Developer</role>
</roles>
<timezone>+8</timezone>
</developer>
</developers>
第三步:准備好GPG工具
我們在本地生成好jar包后,要上傳到中央庫,為了保證上傳過程的數據校驗是對的,Sonatype要求我們使用GPG來進行數據校驗。
gpg --gen-key
出現如下提示后輸入1:
在如下提示后輸入想要的KEY的位數,沒有特別需要的話直接回車也可以:
接着會出現詢問KEY的有效期,默認這是0,也就是說永遠不過期:
接着輸入y並回車確認永久有效。然后會出現下面的提示,要求輸入你的真實姓名:
根據提示輸入姓名,郵箱和備注后,然后會提示輸入用來保護密鑰的密碼(passphrase),如果不需要密碼的話直接回車,如果輸入了密碼那么一定要記住,這個密碼在后面會用到。接下來系統會要求你輸入一些隨機字符,在鍵盤的字母和符號上亂按就可以了,不過別按回車。
注意,這里的姓名和郵箱、密碼 三個東西都要記住。!!
生成成功以后會出現信息:
public and secret key created and signed
要查看現有的公鑰,輸入:
gpg --list-keys
輸出的格式是這個樣子的:
knightliao@conan:~$ gpg --list-keys
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
/home/knightliao/.gnupg/pubring.gpg
-----------------------------------
pub 2048R/XX 2014-07-08
uid 用戶名 <郵箱>
sub 2048R/YY 2014-07-08
這里順便說一下,如果你有多個KEY,想刪除其中的某個KEY,方法是:
gpg --delete-keys XX
生成了key以后,按照Sonatype的要求,我們需要把公鑰上傳到服務器上。輸入:
gpg --keyserver <a href="http://hkp://pool.sks-keyservers.net">hkp://pool.sks-keyservers.net</a> --send-keys XX
這個服務器地址是Sonatype規定的,因此不需要修改。
驗證一下:
gpg --keyserver <a href="http://hkp://pool.sks-keyservers.net">hkp://pool.sks-keyservers.net</a> --recv-keys C67A5D26
如果打印以下,則說明上傳成功:
gpg: requesting key C67A5D26 from hkp server <a href="http://pool.sks-keyservers.net">pool.sks-keyservers.net</a>
gpg: key C67A5D26: "用戶名 <郵箱>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
第四步:注冊Sonatype
就要像Sonatype提出申請了。首先,要到這里申請他們的Jira帳號。獲得帳號以后,到這里提 交一個申請ticket。點擊Create issue, Project要選Support - Open Source Project Repository Hosting,Issue Type選New Project。 再次提醒:groupId的寫法非常重要,要么使用自己擁有的域名。要么使用項目托管的子域名,例如com.github.username。為了節省時 間,如果使用的是自己擁有的域名,那么可以在description里寫清楚,否則客服有可能會問,這樣就一個來回就需要一個工作日了。
一個例子就是:https://issues.sonatype.org/browse/OSSRH-10550
注意,注冊時用戶名和郵箱必須是 第三步里的 用戶名和郵箱。
注冊成功后,他們就會給你發送郵件,然后就可 登錄這里 進行查看: https://oss.sonatype.org/
第五步:修改本地maven的 settings.xml
用上一步注冊時的用戶名和密碼填充這里:
nexus-release 用戶名 密碼
這里的id要和pom.xml文件里面的repository id對應,用戶名和密碼則是Sonatype的Jira帳號和密碼。
第六步:編譯本地代碼
進到 disconf 根目錄下,執行 mvn clean install
然后
cd disconf-core
mvn clean install
如果沒有問題,說明可以准備上傳了。
第七步之一:上傳SNAPSHOT版本代碼
如果你的項目是 SNAPSHOT的,那么 就可以使用本步方法進行上傳,它會上傳到 https://oss.sonatype.org/content/repositories/snapshots
首先,為了后續的操作順利執行,我們要確保項目的整個目錄沒有本地未提交的修改,最好先pull一遍確保后續的步驟里沒有沖突。然后運行:
mvn release:prepare
mvn release:prepare does the following:
- Checks that your local source code does not have any modifications
- Writes a release.properties file with details of what it is doing
- Modifies the pom.xml to the release versions
- Does a build as far as "package" in order to assure itself that it's changes have not broken the build
- Commits the modified pom.xml files to SCM
- Tags the trunk
- Modifies the pom.xml to the next snapshot version
- Commits the modified pom.xml files to SCM
如果命令順利運行結束,那么這個步驟就算完成了。如果中間出現了什么問題,可以在修復問題后再次運行這條命令,如果想要獲得更詳細的信息,可以運行:
mvn release:prepare -X
如果不希望從終止的地方開始,而是想從頭再來的話可以輸入:
mvn release:prepare -Dresume=false
如果想回滾,則
mvn release:rollback
如果這步成功了,則上傳到 https://oss.sonatype.org/content/repositories/snapshots 這里了。
第七步之二:上傳非SNAPSHOT版本代碼
SNAPSHOT一般代表着有Bug版本,線上代碼一般不會使用,因此,非SNAPSHOT版本的包才是我們真正需要的。
不要執行"第七步之一”,執行:
mvn clean deploy -P release -Dgpg.passphrase=第三步中的密碼
mvn release:perform does the following
- Checks out the tagged release into target/checkout
- Forks a "mvn deploy site-deploy"
- Removes the release.properties file
注:mvn clean deploy -P release -Dgpg.passphrase=第三步中的密碼 這句話執行時,如果你的版本是快照的,則上傳快照,如果是非快照的則上傳非快照的,Maven會根據模塊的版本號(pom文件中的version)中是否 帶有-SNAPSHOT來判斷是快照版本還是正式版本。
發布構建
進入https://oss.sonatype.org並登陸,會在左側有個staging Repositories點擊進入,在右側面板找到你的構件,狀態應該是open,你要將其置為closed,點擊上方的close按鈕即可
接下來系統會自動驗證有效性,如果你的Group Id和pom.xml沒有錯誤,狀態會自動變成closed,如果有問題,會在下面提示你那里有問題,加入有問題你可以點擊drop按鈕刪掉這個構件,修改后重新執行步驟7。
接下來你需要點擊release按鈕發布你的構件。
在Issue中通知工作人員
然后回到JIRA中你的Issue,寫個comment,我寫的是Component has been successfully issued.告訴工作人員我發布完成了,等待他們審核。審核通過后我們就可以在中央庫搜索到我們的構件了!搜索的地址 是:http://search.maven.org/
上傳的最佳實踐
- 先讓你的電腦與Github建立連接
- git clone 代碼下下載下來
- 對本地代碼執行 mvn clean install , 解決代碼本身的編譯問題
- 准備好GPG工具
- 申請注冊Sonatype
- 對於SNAPSHOT版本,則執行 mvn release:prepare , 一旦發現有錯誤,需要執行 mvn release:rollback,項目做完后,執行 mvn release:clean
- 對於release版本,則執行 mvn clean deploy -P release -Dgpg.passphrase=第三步中的密碼 。
遇到的一些問題
Return code is: 401, ReasonPhrase: Unauthorized. release:perform
這個是因為你在Maven的settings.xml里的配置與disconf-core的pom.xml配置對應不上來。很可能就是 id沒有匹配。
Maven error: “You don't have a SNAPSHOT project in the reactor projects list.”
如果的項目的版本不是SNAPSHOT,而你卻要用“第七步之一”進行上傳,則會報此錯誤。
i am getting permgen size error in jenkins how to increase
在Sonatype的界面進行上傳
我試過在本地編譯成jar包,然后再在界面上傳。實踐證明這種方法不可取。因為簽名驗證通不過。