使用Gradle發佈構件(Jar)到Maven中央倉庫

OSSRH

在開始之前,先對OSSRH做下了解是很必要的,因爲一開始,我並不知道這是個啥玩兒意。我想和我一樣的人應該還是有很多的。

OSSRHSonatype Open Source Software Repository Hosting Service,爲開源軟件提供maven倉庫託管服務。你可以在上面部署snapshot、release等,最後你可以申請把你的release同步到Maven Central RepositoryMaven中央倉庫)。

個人的理解,OSSRHMaven中央倉庫的前置審批倉庫,只有你完全符合了發佈要求,成功的將你的項目發佈到了OSSRH,纔有機會申請同步到Maven中央倉庫

這篇主要是記錄這整個流程,方便以後自己查閱,同時可以幫助到想做同樣事情的朋友。

1、註冊Sonatype JIRA賬號

JIRA是Atlassian公司出品的項目與事務跟蹤工具,被廣泛應用於缺陷跟蹤、客戶服務、需求收集、流程審批、任務跟蹤、項目跟蹤和敏捷管理等工作領域。

網址:https://issues.sonatype.org/

無非就是填寫下注冊信息,沒有什麼特別的

2、創建一個Issue

填寫資料

可以在頭部看到一個Create的按鈕

sonatype-create-issue-button

會彈出Create Issue表單

sonatype-create-issue-form

Project

選擇Community Support - Open Source Project Repository Hosting (OSSRH)

Issue Type

選擇New Project

Summary

寫個標題做個簡單概述你要做啥。真不知道寫什麼,直接把項目名稱寫上就行,我就這麼幹了哈。

Group Id

  • 自己有域名
    可以使用子域名作爲Group Id 。例:我的項目叫paladin2,那麼就用org.zhangxiao.paladin2作爲Group Id
注意:不能瞎編一個,因爲後面審覈人員會來審覈你是否是該域名的擁有者
  • 自己沒域名
    可以藉助github,例:我的用戶名爲michaelzx,那麼就用com.github.michaelzx.paladin2作爲作爲Group Id

Project URL

要與Group Id一定關聯性

  • 例1:
    Project URL=http://paladin2.zhangxiao.org
    Group Id=org.zhangxiao.paladin2
  • 例2:
    Project URL=https://github.com/michaelzx/Paladin2
    Group Id=com.github.michaelzx.paladin

SCM url

版本倉庫的拉取地址

等待回覆

如果有問題,老外在評論中把問題給你指出來,可以在原有的issue把資料改正確

我之前是犯了個低級的錯誤把Group Id寫成了域名
審覈人員要處理的issue很多,你可能要耐心等待一會,不要急
我之前急了,就重新提交了2個新的issue,最後管理員還是耐心的把重複的issue關閉

如果一切順利,那麼你會收到審覈人員,這樣的一個評論:

sonatype-create-issue-success

3、準備工作

文件要求

爲了確保中央存儲庫中可用組件的質量水平,OSSRH對提交的文件有明確的要求。

一個基礎的提交,應該包含一下文件:

example-application-1.4.7.pom
example-application-1.4.7.pom.asc
example-application-1.4.7.jar
example-application-1.4.7.jar.asc
example-application-1.4.7-sources.jar
example-application-1.4.7-sources.jar.asc
example-application-1.4.7-javadoc.jar
example-application-1.4.7-javadoc.jar.asc
  • 除了jar包和pom文件,JavadocSources是必須的,後面會說到用Gradle的一些插件來生成
  • 每個文件都有一個對應的asc文件,這是GPG簽名文件,可以用於校驗文件

GPG

安裝

說明:後續過程均在OSX環境下

OSX下可以通過brew來安裝gpg命令行工具

$ brew update
$ brew install -v gpg

你會發現從brewgpg命令行工具,做了國際化支持,連help都是中文,贊👍

另外推薦一個工具GPG Suite傳送門
在OSX提供了一個圖形化界面,把GPG作爲鑰匙串來做管理,蠻有意思,不過感覺缺失點功能

Windows下
可以安裝gpg4win,網址:傳送門
頁面最上面有個很大的下載按鈕,點了以後,貌似會讓你捐個款啥的……
不過你可以往下看,有所有版本的列表地址,可以跳過捐款,在祭上一個傳送門
人家只是隱藏的好了一些而已,還是免費的。裝完了以後,在命令行中也可以用gpg了

公鑰、私鑰、簽名

GPG的默認祕鑰類型是RSA,這裏涉及涉及幾個概念公鑰(public-key)、私鑰(secret-key)、簽名(sign/signature)

  • 公鑰私鑰是成對
  • 公鑰加密,私鑰解密。
  • 私鑰簽名,公鑰驗證。

新建一個密鑰

生成了密鑰以後,才能導出公鑰、私鑰

$ gpg --generate-key

創建的時候,會讓你輸入密碼,別輸了以後忘記了,後面gradle插件中會用到。

查看已經生成的密鑰

$ gpg -k
---------------------------------
pub   rsa2048 2019-01-25 [SC] [有效至:2021-01-24]
      72963F6B33D962380B1DC4BD8C446B86DF855F85
uid           [ 絕對 ] zhangxiao'paladin2 <[email protected]>
sub   rsa2048 2019-01-25 [E] [有效至:2021-01-24]

72963F6B33D962380B1DC4BD8C446B86DF855F85,這個叫做密鑰指紋,用來做唯一識別
後面8位DF855F85,叫做標識KEY ID,後面會用到

導出私鑰文件

很多英文文檔或文章中經常出現KeyRingFile這個詞,這個到底是啥?

https://users.ece.cmu.edu/~ad...
Keys are stored in encrypted form. PGP stores the keys in two files on your hard disk; one for public keys and one for private keys. These files are called keyrings. As you use PGP, you will typically add the public keys of your recipients to your public keyring. Your private keys are stored on your private keyring. If you lose your private keyring, you will be unable to decrypt any information encrypted to keys on that ring.
$ gpg --export-secret-keys [密鑰指紋] > secret.gpg

以上命令就可以生成一個二進制的私鑰文件,後面需要配置到gradle中,讓插件幫我們給文件批量簽名

加上-a會生成一個用ASCII 字符封裝的文本文件,方便複製,不過我們這裏不需要

上傳公鑰到公鑰服務器

$ gpg --keyserver keyserver.ubuntu.com --send-keys [密鑰指紋]

在sonatype的倉庫提交後,會需要一個校驗步驟
會需要從多個公鑰服務器上下載匹配的公鑰,然後來校驗你上傳的文件的簽名

sonatype-gpg-signature-validation

簡單的說,你用來簽名的私鑰和你上傳的公鑰,必須要一對,這樣才能通過校驗

以下是sonatype會去拉取的公鑰服務器列表

keys.gnupg.net
pool.sks-keyservers.net
keyserver.ubuntu.com
爲什麼我要特意列出來?
因爲有些文章或教程裏面,都僅給出了一個服務器,如pool.sks-keyservers.net
但是,我在實際操作有時候因爲網絡原因,並不是總能成功上傳。
所以,如果把公鑰上傳到keyserver.ubuntu.com也是OK的。

總結

  1. 密鑰的key id
  2. 密鑰的password
  3. 私鑰的KeyRingFile
  4. 公鑰上傳到了公鑰服務器

準備好了以上幾項,我們就可以開始擼Gradle了

有些文章說,最好是先生成一個吊銷憑證備用,暫時不知道什麼場景下會用到

4、配置Gradle插件

Gradle版本:4.10.2
start.spring.io中生成的gradle工程,是用4.10.2。所以我就這個版本爲標準。

signinghttps://docs.gradle.org/4.10....
maven-publishhttps://docs.gradle.org/4.10....

主要核心就是以上兩個插件

修改build.gradle

// ... 在最下面新增以下代碼

apply plugin: 'maven-publish'
apply plugin: 'signing'

task sourcesJar(type: Jar) {
    from sourceSets.main.allJava
    classifier = 'sources'
}

task javadocJar(type: Jar) {
    from javadoc
    classifier = 'javadoc'
}


publishing {
    // 定義發佈什麼
    publications {
        mavenJava(MavenPublication) {
            // groupId = project.group
            // artifactId = project.name
            // version = project.version
            // groupId,artifactId,version,如果不定義,則會按照以上默認值執行
            from components.java
            artifact sourcesJar
            artifact javadocJar
            pom {
                // 構件名稱
                // 區別於artifactId,可以理解爲artifactName
                name = 'Paladin2 Common'
                // 構件描述
                description = 'Paladin2 Common library'
                // 構件主頁
                url = 'https://paladin2.zhangxiao.org'
                // 許可證名稱和地址
                licenses {
                    license {
                        name = 'The Apache License, Version 2.0'
                        url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                // 開發者信息
                developers {
                    developer {
                        name = '聽風.Michael'
                        email = '[email protected]'
                    }
                }
                // 版本控制倉庫地址
                scm {
                    url = 'https://github.com/michaelzx/Paladin2'
                    connection = 'scm:git:git://github.com/michaelzx/Paladin2.git'
                    developerConnection = 'scm:git:ssh://[email protected]:michaelzx/Paladin2.git'
                }
            }
        }
    }
    // 定義發佈到哪裏
    repositories {
        maven {
            // 從命令行參數中獲取賬號密碼,這樣你把這個文件傳到GitHub這關係也不大,不會暴露賬號密碼
            // -DsonatypeUsername=michaelzx -DsonatypePassword=xxxxxx
            def sonatypeUsername = System.getProperty("sonatypeUsername")
            def sonatypePassword = System.getProperty("sonatypePassword")
            // 打印出來看看,你參數設置對了沒
            println("sonatypeUsername:" + sonatypeUsername)
            println("sonatypePassword:" + sonatypePassword)
            url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
            credentials {
                // 這裏就是之前在issues.sonatype.org註冊的賬號
                // 直接寫在不太安全,應該是有辦法通過參數,配置到工程之外
                username sonatypeUsername
                password sonatypePassword
            }
        }
    }
}

signing {
    sign publishing.publications.mavenJava
}


javadoc {
    // <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    // 防止本地打開中文亂碼
    options.addStringOption("charset", "UTF-8")
}

在工程根目錄下新增gradle.properties

signing.keyId=密鑰keyId
signing.password=密鑰password
signing.secretKeyRingFile=私鑰keyRingFile路徑

如果要提交到GitHub上,那麼keyId,password好像是暴露了,不過感覺好像也沒什麼關係,把私鑰保護好就好了

5、提交到Sonatype倉庫

首先,用Gradle執行publishToMavenLocal任務,先在本地發佈下,看看生成了哪些文件,或還有什麼問題

然後,用Gradle執行publish任務,發佈到指定的maven倉庫

如果沒有報錯,那麼恭喜你,已經成功提交到了sonatype的倉庫中

但是提交成功,並不代表發佈成功

6、到Sonatype OSS發佈

用你之前註冊的賬號密碼,登錄:https://oss.sonatype.org/

登錄後查看左側的Build Promotion->Staging Repositories

你的提交,會出現在最下面,至於其他是啥,我也不太清楚😂

sonatype-staging-repository-close

Close

你的提交在未處理前,是open狀態,然後點擊Close按鈕。

一開始不太明白這個Close是啥意思,後來看了下,主要按照中央倉庫的要求來驗證下你上傳到文件
簽名就是其中一個步驟,會去公鑰服務器拉取公鑰,然後來驗證你所有的文件

需要等待一會,等它執行完畢,狀態會從open變成closed

如果碰到錯誤的話,仔細看下Activity選項卡,執行了什麼步驟,那個步驟出現了什麼錯誤,很清晰的

Release

一般情況下,感覺如果順利close後,再次選中點擊Release,耐心等待一會,就大功告成了!

可以在側邊欄Artifact Search中搜索下你的groupId,此時應該能看到對應的構件名稱和版本了

7、回覆Issue

但是很抱歉,到此爲止,你的jar包,還不會同步到maven倉庫中

你需要在你原先創建issue中,告訴下管理人員,你已經完成了第一次發佈

我用我蹩腳的英文,回覆如下:

I have already completed the first release.

然後管理人員給我回復了:

Central sync is activated for org.zhangxiao.paladin2. After you successfully release, your component will be published to Central, typically within 10 minutes, though updates to search.maven.org can take up to two hours.

OK,至此,你的構建就會同步到Maven Central Repository了。

8、同步需要多久

可能你會像我一樣很着急,啥時候可以用,怎麼還搜不到呢~。~
從sonatype同步到中央倉庫,的確是需要一定的時間

不過根據我的觀察,文件的同步,會早於索引的同步

比如,比如你等了半天,然後 https://search.maven.org/ 上搜一下依然搜不到
那麼,你可以去 https://repo1.maven.org/maven2/ 上按照座標找下,是否能找到你的包

如果能找到,那你就可以開始引用它了

9、新版本更新

只要完成第一個發佈,後續就不需要再創建issue了,只要重複5-6步驟可以了。

你可以在groupId範圍內發佈任意名稱的構件

結束語

以前在NPM倉庫中發佈過自己的東西。相比之下,Maven倉庫的發佈流程,讓人感覺嚴謹很多。

趕緊一起在Maven全球中央倉庫中,留下你自己專屬的印記吧!

一定會讓你感覺棒棒的^_^

參考文章

https://central.sonatype.org/...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章