Android Studio使用Gradle上传AAR至Maven
這幾天有個開源library要上傳到Maven Central Repository,找到某大神的博客,他用Maven上傳的庫,我依葫蘆畫瓢搞了兩天,臥槽,可能是人品問題,mvn一直報一個莫名其妙的異常,Google了半天完全沒有頭緒,恨死那個Windows的黑框框了。
后來從國外某大神的開源project那學到到可以用Gradle來上傳AAR到maven central repository,終于可以和那個坑爹的黑框框說good bye了- -
前期工作
前期我們要做一些準備工作,包括:
打開Sonatype JIRA注冊帳號,注冊好之后打開Create Issue創建一個JIRA ticket,一個JIRA ticket對應一個項目。
其中Summary填寫項目名,例如AndroidTagGroup;Description填寫項目描述;Group Id必須是項目包名的父級,比如我的包名為me.gujun.android.taggroup,那么為了我所有的項目都可以發布,Group Id填寫為me.gujun。
其它按照提示填寫,完成后大概兩個工作日左右,該issue會變成RESOLVED狀態,表示可用,在可用前除了最后一步正式發布之外,其它都可以正常進行。
使用GnuPG生成密鑰
發布release版本時需要對上傳的文件加密和簽名,GPG用于生成簽名,管理密鑰。
上傳前我們需要做兩件事:
安裝
下載地址:GPG、GPG for Windows
安裝之后驗證一下
$ 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除了姓名、郵箱、備注外其它都可以使用默認設置,最后需要輸入一個passphrase,妥善保管這個口令,后面配置Gradle腳本時需要用到。
查看密鑰
查看公鑰:
$ 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,需要上傳給服務器。
查看私鑰:
$ 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腳本時需要用到。
上傳公鑰
$ gpg --keyserver hkp://pool.sks-keyservers.net --send-keys F874D485gpg: sending key F874D485 to hkp server pool.sks-keyserver.net把之前生成的公鑰上傳至服務器,系統需要你上傳的公鑰來驗證發布時的文件。
F874D485為之前生成的公鑰的keyId,一旦提交至一個key server,公鑰會自動同步到其它key server。
配置Gradle腳本
Gradle腳本使用了開源項目gradle-mvn-push,Thx Chris大神!
添加maven-push.gradle
把下面的腳本復制到工程目錄,新建文件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文件中設置屬性,把屬性修改成自己的。
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表示發布的是版本快照。
GROUP設置成項目包名,注意,父級要和之前創建JIRA ticket時的Group Id一致。
配置Project構建腳本
之后修改工程目錄下的build.gradle:
buildscript {repositories {jcenter()}dependencies {classpath 'com.android.tools.build:gradle:1.0.1'} }allprojects {version = VERSION_NAMEgroup = GROUPrepositories {jcenter()} }配置Module屬性
工程配置好之后,我們還需要給上傳的Module配置(我們的工程中可能有多個Module需要上傳到倉庫中,要給每個Module添加配置)
給需要上傳到Maven倉庫的Module提供一個gradle.properties文件:
POM_NAME=Android TagGroup Library POM_ARTIFACT_ID=library POM_PACKAGING=aarPOMARTIFACTID設置成Module名。
這個組件對應的依賴已經浮出水面了:GROUP:POMARTIFACTID:VERSION_NAME
即
me.gujun.android.taggroup:library:1.0
配置Module構建腳本
修改Module目錄的build.gradle,在最后加上:
apply from: '../maven-push.gradle'配置全局屬性
這個全局的Gradle配置文件默認在USER_HOME/.gradle/gradle.properties,沒有的話可以新建一個。
在這里配置Maven服務器的用戶名和密碼,還需要配置之前生成的keyId, password和一個secretKeyRingFile,這個文件用來在上傳release版本時對文件進行簽名。
NEXUS_USERNAME=2dxgujun NEXUS_PASSWORD=123456signing.keyId=F874D485 signing.password=123456 signing.secretKeyRingFile=C:/Users/PingGe/AppData/Roaming/gnupg/secring.gpgWindows的secretKeyRingFile路徑如上所示,其它系統可以使用gpg --list-secret-keys命令查看。
部署release版本
所有的配置已經完成,現在可以上傳了,在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登錄,選擇左側Build Promotion菜單中的Staging Repositories選項,在出現的選項卡右上角的搜索框輸入關鍵字,篩選出你上傳的組件所在的repository。
部署時創建的repository會根據部署項目的groupId來命名,例如我的groupId為me.gujun,那么我的repository即為megujun-xxxx,后面的xxxx為4個數字,初次部署為1000,后面每次部署這個數字都會+1。選擇這個repository,列表下面的面板會顯示一些詳細信息。
正式發布
部署完成之后,上傳的組件會存儲在一個獨立的臨時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。
注意:如果你是第一次發布,需要到之前創建的JIRA ticket評論一下,告訴他們你已經release了,需要同步下。
Gradle文件的配置可以參考我的項目:AndroidTagGroup
我的JIRA ticket:OSSRH-13721
遇到問題
androidJavadocs 錯誤: 編碼GBK的不可映射字符。
解決方法:把中文注釋替換成英文注釋。
androidJavadocs task 錯誤:不允許使用自關閉元素。
解決方法:刪除注釋中<br/>、<p/>之類的標簽,把整段注釋內容使用<p></p>標簽包裹起來。
Close時評估出現錯誤:Failed: Signature Validation
解決方法:重試上傳GPG生成的keyId
備注
在正式發布時可能會出現403錯誤:
Release failed Nexus returned an error: ERROR 403: Forbidden這是因為之前創建的JIRA ticket的狀態還未變成RESOLVED,等待可用既可。
參考:
本文出自2dxgujun,轉載時請注明出處及相應鏈接。
總結
以上是生活随笔為你收集整理的Android Studio使用Gradle上传AAR至Maven的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AsyncHttpClient 源码分析
- 下一篇: butterknife 源码分析