前言
先來閒侃一下,這幾天一直在搞這東東,從一點不知道到大體知道,再到知道完整流程,真的看了不是大神的帖子,特別是UK的chrisbanes大神,寫了一個標準的gradle腳本,真的很是用,英文不好,所以看起來費了點勁,廢話不多說了,下面來講講步驟吧。
大概有以下 5 個步驟:
- 到 issues.sonatype.org 註冊個帳號,申請發佈權限
- 編寫 Gradle 自動化發佈腳本
- 下載 GPGTools,創建 Signing Key
- 執行 Gradle 發佈腳本
- 申請激活 Maven Central Sync 進程
1. 申請 Maven Central 發佈權限
第一步就是註冊賬號,這一步就省略掉吧。
這裏需要特別說明的是Group Id,如果你是託管在Github或者Git@OSC 可以使用com.github.XXX或者net.oschina.XXX,我之前註冊了個自己的域名com.github.xxl6097,所以在此填寫這個group,剩下的可以依照實際情況填寫,例如託管的地址等等
- 等待Issue審批
截圖爲這個Issue的截圖,當看到 Configuration has been prepared, now you can: 這句話的時候,說明你已經通過了Issue的審批,可以上傳構建了。
2. 編寫 Gradle 發佈腳本
首先展示一下我的項目目錄,方便下面做說明:
library就是我們的庫,也就是這邊文章的主角色了,sample僅僅是一個使用實例而已。
配置Project屬性(library)
在工程目錄下的gradle.properties文件中設置屬性,把屬性修改成自己的。
#版本名稱
VERSION_NAME=1.0.0
#版本號
VERSION_CODE=1
#唯一標識
GROUP=com.github.xxl6097
#項目描述信息
POM_DESCRIPTION=this android crash library
#項目託管主頁
POM_URL=https://github.com/xxl6097/CustomOnCrash
#項目託管主頁
POM_SCM_URL=https://github.com/xxl6097/CustomOnCrash
#項目託管地址
POM_SCM_CONNECTION=scm:[email protected]:xxl6097/CustomOnCrash.git
POM_SCM_DEV_CONNECTION=scm:[email protected]:xxl6097/CustomOnCrash.git
POM_LICENCE_NAME=The Apache Software License, Version 2.0
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
POM_LICENCE_DIST=repo
POM_DEVELOPER_ID=uuxia
POM_DEVELOPER_NAME=uuxia xxl6097
POM_DEVELOPER_EMAIL[email protected]
POM_INCEPTION_YEAR=2015
ANDROID_BUILD_TARGET_SDK_VERSION=19
ANDROID_BUILD_TOOLS_VERSION=19.0.3
ANDROID_BUILD_SDK_VERSION=19
注意:VERSION_NAME後面加-SNAPSHOT表示發佈的是版本快照。
GROUP設置成項目包名,注意,父級要和之前創建JIRA ticket時的Group Id一致。
配置Module屬性(library)
修改項目根目錄下的gradle.properties,添加項目的信息:
工程配置好之後,我們還需要給上傳的Module配置(我們的工程中可能有多個Module需要上傳到倉庫中,要給每個Module添加配置)
給需要上傳到Maven倉庫的Module提供一個gradle.properties文件:
最後到開源庫所在的 module 目錄,添加編譯信息到 library\gradle.properties :
POM_NAME=CustomOnCrash
POM_ARTIFACT_ID=customoncrash
POM_PACKAGING=aar
POMARTIFACTID設置成Module名。
這個組件對應的依賴已經浮出水面了:GROUP:POMARTIFACTID:VERSION_NAME
即:
com.github.xxl6097:customoncrash:1.0.0
配置Module構建腳本(library)
感謝 Chris Banes 大神提供的腳本,稍作修改,弄了一個我自己的版本。
https://github.com/xxl6097/gradle-mvn-push/blob/master/gradle-mvn-push.gradle
將上面的腳本放到項目的根目錄下也就是library同級目錄,然後到開源庫所在的 module 目錄(library目錄),添加以下代碼 library\build.gradle :
apply from: '../gradle-mvn-push.gradle'
配置全局屬性
這個全局的Gradle配置文件默認在USER_HOME/.gradle/gradle.properties,沒有的話可以新建一個。
在這裏配置Maven服務器的用戶名和密碼,還需要配置之前生成的keyId, password和一個secretKeyRingFile,這個文件用來在上傳release版本時對文件進行簽名。
#nexus的用戶名
NEXUS_USERNAME=xxl6097
#nexus的密碼
NEXUS_PASSWORD=*******
#GPG祕鑰ID
signing.keyId=FB58CB54
#GPG祕鑰密碼
signing.password=********
#GPG祕鑰文件路徑
signing.secretKeyRingFile=C:/Users/uuxia/AppData/Roaming/gnupg/secring.gpg
Windows的secretKeyRingFile路徑如上所示,其它系統可以使用gpg –list-secret-keys命令查看。
3. 下載 GPGTools,創建 Signing Key
發佈release版本時需要對上傳的文件加密和簽名,GPG用於生成簽名,管理密鑰。
上傳前我們需要做兩件事:
- 生成密鑰對
- 上傳密鑰
安裝
- 下載地址:GPG
- 安裝之後驗證一下:
- 生成密鑰
gpg --gen-key
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)
Your selection? 1
RSA keys may be between 1024 and 8192 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 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) 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: Special Leung(Testing)
Email address: [email protected]
Comment: This is just a testing key.
You selected this USER-ID:
"uuxia (This is just a testing key.) <[email protected]>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.
...
pub 2048R/8C1761A2 2015-01-24
Key fingerprint = xxx
uid [ultimate] uuxia (This is just a testing key.) <[email protected]>
sub 2048R/E32D1186 2015-01-24
除了姓名、郵箱、備註外其它都可以使用默認設置,最後需要輸入一個passphrase,妥善保管這個口令,後面配置Gradle腳本時需要用到。
- 查看密鑰
1.查看公鑰:
C:\Users\uuxia\Desktop\CSmtp_v2_4_ssl>gpg –list-keys
C:/Users/uuxia/AppData/Roaming/gnupg\pubring.gpg
———————————————— pub 2048R/FB58CB54 2015-12-15 uid uuxia (This is my personal key)
<[email protected]> sub 2048R/85534FD0 2015-12-15
輸出的路徑爲公鑰文件,FB58CB54 爲keyId,需要上傳給服務器。
2.查看私鑰:
C:\Users\uuxia\Desktop\CSmtp_v2_4_ssl>gpg –list-secret-keys
C:/Users/uuxia/AppData/Roaming/gnupg\secring.gpg
———————————————— sec 2048R/FB58CB54 2015-12-15 uid uuxia (This is my personal key)
<[email protected]> ssb 2048R/85534FD0 2015-12-15
私鑰文件路徑在配置Gradle腳本時需要用到。
3.上傳公鑰
gpg –keyserver hkp://pool.sks-keyservers.net –send-keys FB58CB54
gpg: sending key FB58CB54 to hkp server pool.sks-keyserver.net
把之前生成的公鑰上傳至服務器,系統需要你上傳的公鑰來驗證發佈時的文件。
FB58CB54 爲之前生成的公鑰的keyId,一旦提交至一個key server,公鑰會自動同步到其它key server。
4. 執行 Gradle 發佈腳本
所有的配置已經完成,現在可以上傳了,在Android Studio的Terminal輸入命令:
gradle uploadArchives
如果上傳成功,最後你會看到控制檯打印類似的信息:
E:\HeT\maven\CustomOnCrash\library>gradle uploadArchives
2475431305
2475431305
2475431305
:library:androidJavadocs
E:\HeT\maven\CustomOnCrash\library\src\main\java\uuxia\com\library\ui\DefaultErrorActivity.java:36: 錯誤: 找不到符號
import uuxia.com.library.R;
^
符號: 類 R
位置: 程序包 uuxia.com.library
1 個警告
:library:androidJavadocsJar
:library:androidSourcesJar
:library:compileLint
:library:copyReleaseLint UP-TO-DATE
:library:mergeReleaseProguardFiles UP-TO-DATE
:library:preBuild UP-TO-DATE
:library:preReleaseBuild UP-TO-DATE
:library:checkReleaseManifest
:library:prepareReleaseDependencies
:library:compileReleaseAidl UP-TO-DATE
:library:compileReleaseRenderscript UP-TO-DATE
:library:generateReleaseBuildConfig UP-TO-DATE
:library:generateReleaseAssets UP-TO-DATE
:library:mergeReleaseAssets UP-TO-DATE
:library:generateReleaseResValues UP-TO-DATE
:library:generateReleaseResources UP-TO-DATE
:library:packageReleaseResources UP-TO-DATE
:library:processReleaseManifest UP-TO-DATE
:library:processReleaseResources UP-TO-DATE
:library:generateReleaseSources UP-TO-DATE
:library:processReleaseJavaRes UP-TO-DATE
:library:compileReleaseJavaWithJavac
注: E:\HeT\maven\CustomOnCrash\library\src\main\java\uuxia\com\library\ui\DefaultErrorActivity.java使用或覆蓋了已過時的
API。
注: 有關詳細信息, 請使用 -Xlint:deprecation 重新編譯。
:library:packageReleaseJar
:library:compileReleaseNdk UP-TO-DATE
:library:packageReleaseJniLibs UP-TO-DATE
:library:packageReleaseLocalJar UP-TO-DATE
:library:packageReleaseRenderscript UP-TO-DATE
:library:bundleRelease
:library:signArchives
:library:uploadArchives
Could not find metadata com.github.xxl6097:customoncrash/maven-metadata.xml in remote (https://oss.sonatype.org/service/
local/staging/deploy/maven2/)
BUILD SUCCESSFUL
Total time: 2 mins 20.451 secs
上傳成功後,打開Sonatype Nexus Professional登錄,選擇左側Build Promotion菜單中的Staging Repositories選項,在出現的選項卡右上角的搜索框輸入關鍵字,篩選出你上傳的組件所在的repository。
部署時創建的repository會根據部署項目的groupId來命名,例如我的groupId爲com.github.xxl6097,那麼我的repository即爲xxl6097-xxxx,後面的xxxx爲4個數字,初次部署爲1000,後面每次部署這個數字都會+1。選擇這個repository,列表下面的面板會顯示一些詳細信息。
5. 激活 Maven Central Sync 進程
部署完成之後,上傳的組件會存儲在一個獨立的臨時staging repository,在正式發佈之前如果你在測試時遇到任何問題,都可以刪除這個staging repository,在修復之後重新部署。正式發佈纔會同步到maven central repository。
通常情況下正式發佈操作需要手動完成。
首先打開Sonatype Nexus Professional登錄,打開Staging Repositories列表,篩選出之前部署的repository。
部署完成之後,這個repository會處於Open狀態,你可以切換到Content標籤頁檢查這個repository,如果確信沒有問題,可以點擊列表上面的Close按鈕,這樣會觸發系統對這個repository進行評估。
如果你的組件不滿足評估要求,Close操作會失敗。
遇到這種情況,可以切換到Activity標籤查看系統評估時出現的具體問題,修復問題,再嘗試Close操作;如果需要重新部署,可以點擊列表上面的Drop按鈕刪除這個repository,在本地修改之後,再重新部署。
成功close之後,可以點擊Release按鈕正式發佈repository,組件會被移動到OSSRH的release repository,這個倉庫會同步到maven central repository。
Gradle文件的配置可以參考我的項目:CustomOnCrash
我的JIRA ticket:OSSRH-19416
遇到問題
androidJavadocs 錯誤: 編碼GBK的不可映射字符。
解決方法:把中文註釋替換成英文註釋。
androidJavadocs task 錯誤:不允許使用自關閉元素。
解決方法:刪除註釋中
、
之類的標籤,把整段註釋內容使用
標籤包裹起來。Close時評估出現錯誤:Failed: Signature Validation
解決方法:重試上傳GPG生成的keyId
備註
在正式發佈時可能會出現403錯誤:
Release failed
Nexus returned an error: ERROR 403: Forbidden
這是因爲之前創建的JIRA ticket的狀態還未變成RESOLVED,等待可用既可。
6. 結語
總的來說,發佈還是挺方便的,人工審覈可能會浪費點時間,偶爾還可能遇到些問題,不過 sonatype 還是很專業的,將你遇到的問題告訴他們之後,都可以得到一個有效的解決辦法。
不過最近 Android Studio 把 jCentral 作爲默認的節點了,也許下次就得折騰 jCentral 了。
Reference:
- Pushing AARs to Maven Central
- Working with PGP signatures
- Releasing the deployment
- Release the deployment to the central repository