Android Studio使用Gradle上传AAR至Maven
這幾天有個(gè)開源library要上傳到Maven Central Repository,找到某大神的博客,他用Maven上傳的庫,我依葫蘆畫瓢搞了兩天,臥槽,可能是人品問題,mvn一直報(bào)一個(gè)莫名其妙的異常,Google了半天完全沒有頭緒,恨死那個(gè)Windows的黑框框了。
后來從國外某大神的開源project那學(xué)到到可以用Gradle來上傳AAR到maven central repository,終于可以和那個(gè)坑爹的黑框框說good bye了- -
前期工作
前期我們要做一些準(zhǔn)備工作,包括:
打開Sonatype JIRA注冊帳號,注冊好之后打開Create Issue創(chuàng)建一個(gè)JIRA ticket,一個(gè)JIRA ticket對應(yīng)一個(gè)項(xiàng)目。
其中Summary填寫項(xiàng)目名,例如AndroidTagGroup;Description填寫項(xiàng)目描述;Group Id必須是項(xiàng)目包名的父級,比如我的包名為me.gujun.android.taggroup,那么為了我所有的項(xiàng)目都可以發(fā)布,Group Id填寫為me.gujun。
其它按照提示填寫,完成后大概兩個(gè)工作日左右,該issue會變成RESOLVED狀態(tài),表示可用,在可用前除了最后一步正式發(fā)布之外,其它都可以正常進(jìn)行。
使用GnuPG生成密鑰
發(fā)布release版本時(shí)需要對上傳的文件加密和簽名,GPG用于生成簽名,管理密鑰。
上傳前我們需要做兩件事:
安裝
下載地址:GPG、GPG for Windows
安裝之后驗(yàn)證一下
$ gpg --versiongpg (GnuPG) 2.0.26 (Gpg4win 2.2.3) libgcrypt 1.6.2 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>生成密鑰
$ gpg --gen-key除了姓名、郵箱、備注外其它都可以使用默認(rèn)設(shè)置,最后需要輸入一個(gè)passphrase,妥善保管這個(gè)口令,后面配置Gradle腳本時(shí)需要用到。
查看密鑰
查看公鑰:
$ gpg --list-keysC:/Users/PingGe/AppData/Roaming/gnupg/pubring.gpg ------------------------------------------------- pub 2048R/F874D485 2015-02-10 uid [ultimate] JunGu (Sonatype) <2dxgujun@gmail.com> sub 2048R/F27758E5 2015-02-10輸出的路徑為公鑰文件,F874D485為keyId,需要上傳給服務(wù)器。
查看私鑰:
$ gpg --list-secret-keysC:/Users/PingGe/AppData/Roaming/gnupg/secring.gpg ------------------------------------------------- sec 2048R/F874D485 2015-02-10 uid JunGu (Sonatype) <2dxgujun@gmail.com> ssb 2048R/F27758E5 2015-02-10私鑰文件路徑在配置Gradle腳本時(shí)需要用到。
上傳公鑰
$ gpg --keyserver hkp://pool.sks-keyservers.net --send-keys F874D485gpg: sending key F874D485 to hkp server pool.sks-keyserver.net把之前生成的公鑰上傳至服務(wù)器,系統(tǒng)需要你上傳的公鑰來驗(yàn)證發(fā)布時(shí)的文件。
F874D485為之前生成的公鑰的keyId,一旦提交至一個(gè)key server,公鑰會自動同步到其它key server。
配置Gradle腳本
Gradle腳本使用了開源項(xiàng)目gradle-mvn-push,Thx Chris大神!
添加maven-push.gradle
把下面的腳本復(fù)制到工程目錄,新建文件maven-push.gradle。
/* * Copyright 2013 Chris Banes * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */apply plugin: 'maven' apply plugin: 'signing'def isReleaseBuild() {return VERSION_NAME.contains("SNAPSHOT") == false }def getReleaseRepositoryUrl() {return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL: "https://oss.sonatype.org/service/local/staging/deploy/maven2/" }def getSnapshotRepositoryUrl() {return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL: "https://oss.sonatype.org/content/repositories/snapshots/" }def getRepositoryUsername() {return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "" }def getRepositoryPassword() {return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "" }afterEvaluate { project ->uploadArchives {repositories {mavenDeployer {beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }pom.groupId = GROUPpom.artifactId = POM_ARTIFACT_IDpom.version = VERSION_NAMErepository(url: getReleaseRepositoryUrl()) {authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())}snapshotRepository(url: getSnapshotRepositoryUrl()) {authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())}pom.project {name POM_NAMEpackaging POM_PACKAGINGdescription POM_DESCRIPTIONurl POM_URLscm {url POM_SCM_URLconnection POM_SCM_CONNECTIONdeveloperConnection POM_SCM_DEV_CONNECTION}licenses {license {name POM_LICENCE_NAMEurl POM_LICENCE_URLdistribution POM_LICENCE_DIST}}developers {developer {id POM_DEVELOPER_IDname POM_DEVELOPER_NAME}}}}}}signing {required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }sign configurations.archives}task apklib(type: Zip){appendix = extension = 'apklib'from 'AndroidManifest.xml'into('res') {from 'res'}into('src') {from 'src'}}task androidJavadocs(type: Javadoc) {source = android.sourceSets.main.java.srcDirsclasspath += project.files(android.getBootClasspath() .join(File.pathSeparator))}task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {classifier = 'javadoc'from androidJavadocs.destinationDir}task androidSourcesJar(type: Jar) {classifier = 'sources'from android.sourceSets.main.java.srcDirs}artifacts {archives androidSourcesJararchives androidJavadocsJararchives apklib} }配置Project屬性
在工程目錄下的gradle.properties文件中設(shè)置屬性,把屬性修改成自己的。
VERSION_NAME=1.0 VERSION_CODE=1 GROUP=me.gujun.android.taggroupPOM_DESCRIPTION=Android Library to display a set of tags POM_URL=https://github.com/2dxgujun/AndroidTagGroup POM_SCM_URL=https://github.com/2dxgujun/AndroidTagGroup POM_SCM_CONNECTION=scm:https://github.com/2dxgujun/AndroidTagGroup.git POM_SCM_DEV_CONNECTION=scm:https://github.com/2dxgujun/AndroidTagGroup.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=2dxgujun POM_DEVELOPER_NAME=Jun GuSNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2注意:VERSION_NAME后面加-SNAPSHOT表示發(fā)布的是版本快照。
GROUP設(shè)置成項(xiàng)目包名,注意,父級要和之前創(chuàng)建JIRA ticket時(shí)的Group Id一致。
配置Project構(gòu)建腳本
之后修改工程目錄下的build.gradle:
buildscript {repositories {jcenter()}dependencies {classpath 'com.android.tools.build:gradle:1.0.1'} }allprojects {version = VERSION_NAMEgroup = GROUPrepositories {jcenter()} }配置Module屬性
工程配置好之后,我們還需要給上傳的Module配置(我們的工程中可能有多個(gè)Module需要上傳到倉庫中,要給每個(gè)Module添加配置)
給需要上傳到Maven倉庫的Module提供一個(gè)gradle.properties文件:
POM_NAME=Android TagGroup Library POM_ARTIFACT_ID=library POM_PACKAGING=aarPOMARTIFACTID設(shè)置成Module名。
這個(gè)組件對應(yīng)的依賴已經(jīng)浮出水面了:GROUP:POMARTIFACTID:VERSION_NAME
即
me.gujun.android.taggroup:library:1.0
配置Module構(gòu)建腳本
修改Module目錄的build.gradle,在最后加上:
apply from: '../maven-push.gradle'配置全局屬性
這個(gè)全局的Gradle配置文件默認(rèn)在USER_HOME/.gradle/gradle.properties,沒有的話可以新建一個(gè)。
在這里配置Maven服務(wù)器的用戶名和密碼,還需要配置之前生成的keyId, password和一個(gè)secretKeyRingFile,這個(gè)文件用來在上傳release版本時(shí)對文件進(jìn)行簽名。
NEXUS_USERNAME=2dxgujun NEXUS_PASSWORD=123456signing.keyId=F874D485 signing.password=123456 signing.secretKeyRingFile=C:/Users/PingGe/AppData/Roaming/gnupg/secring.gpgWindows的secretKeyRingFile路徑如上所示,其它系統(tǒng)可以使用gpg --list-secret-keys命令查看。
部署release版本
所有的配置已經(jīng)完成,現(xiàn)在可以上傳了,在Android Studio的Terminal輸入命令:
gradle uploadArchives如果上傳成功,最后你會看到控制臺打印類似的信息:
Uploading: me/gujun/android/taggroup/library/1.0/library-1.0.aar to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 19K from remote Uploaded 19K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0.aar.asc to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 0K from remote Uploaded 0K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0-sources.jar to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 7K from remote Uploaded 7K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0-sources.jar.asc to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 0K from remote Uploaded 0K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0.apklib to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 11K from remote Uploaded 11K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0.apklib.asc to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 0K from remote Uploaded 0K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0-javadoc.jar to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 34K from remote Uploaded 34K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0-javadoc.jar.asc to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 0K from remote Uploaded 0K Uploading: me/gujun/android/taggroup/library/1.0/library-1.0.pom.asc to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2 Transferring 0K from remote Uploaded 0K上傳成功后,打開Sonatype Nexus Professional登錄,選擇左側(cè)Build Promotion菜單中的Staging Repositories選項(xiàng),在出現(xiàn)的選項(xiàng)卡右上角的搜索框輸入關(guān)鍵字,篩選出你上傳的組件所在的repository。
部署時(shí)創(chuàng)建的repository會根據(jù)部署項(xiàng)目的groupId來命名,例如我的groupId為me.gujun,那么我的repository即為megujun-xxxx,后面的xxxx為4個(gè)數(shù)字,初次部署為1000,后面每次部署這個(gè)數(shù)字都會+1。選擇這個(gè)repository,列表下面的面板會顯示一些詳細(xì)信息。
正式發(fā)布
部署完成之后,上傳的組件會存儲在一個(gè)獨(dú)立的臨時(shí)staging repository,在正式發(fā)布之前如果你在測試時(shí)遇到任何問題,都可以刪除這個(gè)staging repository,在修復(fù)之后重新部署。正式發(fā)布才會同步到maven central repository。
通常情況下正式發(fā)布操作需要手動完成。
首先打開Sonatype Nexus Professional登錄,打開Staging Repositories列表,篩選出之前部署的repository。
部署完成之后,這個(gè)repository會處于Open狀態(tài),你可以切換到Content標(biāo)簽頁檢查這個(gè)repository,如果確信沒有問題,可以點(diǎn)擊列表上面的Close按鈕,這樣會觸發(fā)系統(tǒng)對這個(gè)repository進(jìn)行評估。
如果你的組件不滿足評估要求,Close操作會失敗。
遇到這種情況,可以切換到Activity標(biāo)簽查看系統(tǒng)評估時(shí)出現(xiàn)的具體問題,修復(fù)問題,再嘗試Close操作;如果需要重新部署,可以點(diǎn)擊列表上面的Drop按鈕刪除這個(gè)repository,在本地修改之后,再重新部署。
成功close之后,可以點(diǎn)擊Release按鈕正式發(fā)布repository,組件會被移動到OSSRH的release repository,這個(gè)倉庫會同步到maven central repository。
注意:如果你是第一次發(fā)布,需要到之前創(chuàng)建的JIRA ticket評論一下,告訴他們你已經(jīng)release了,需要同步下。
Gradle文件的配置可以參考我的項(xiàng)目:AndroidTagGroup
我的JIRA ticket:OSSRH-13721
遇到問題
androidJavadocs 錯(cuò)誤: 編碼GBK的不可映射字符。
解決方法:把中文注釋替換成英文注釋。
androidJavadocs task 錯(cuò)誤:不允許使用自關(guān)閉元素。
解決方法:刪除注釋中<br/>、<p/>之類的標(biāo)簽,把整段注釋內(nèi)容使用<p></p>標(biāo)簽包裹起來。
Close時(shí)評估出現(xiàn)錯(cuò)誤:Failed: Signature Validation
解決方法:重試上傳GPG生成的keyId
備注
在正式發(fā)布時(shí)可能會出現(xiàn)403錯(cuò)誤:
Release failed Nexus returned an error: ERROR 403: Forbidden這是因?yàn)橹皠?chuàng)建的JIRA ticket的狀態(tài)還未變成RESOLVED,等待可用既可。
參考:
本文出自2dxgujun,轉(zhuǎn)載時(shí)請注明出處及相應(yīng)鏈接。
總結(jié)
以上是生活随笔為你收集整理的Android Studio使用Gradle上传AAR至Maven的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AsyncHttpClient 源码分析
- 下一篇: butterknife 源码分析