教你如何將開源項目發佈到maven中央倉庫

如何將開源項目發佈到maven中央倉庫,讓別人經過依賴使用你的開源項目,想必不少朋友都有過這個想法。html

去年我就想將本身開源的一個miniexcel工具包發佈到maven倉庫,在項目中經過依賴導入使用,但那時候感受太麻煩了,而後看到有文章介紹說可使用jitpack,這個就很是簡單了。可是最近在項目中,因爲是使用maven,配置jitpack老是導入不了依賴,一直報錯,爲了避免拖慢進度,我仍是放棄了使用這個工具。java

所以,我仍是想將項目打包發佈到maven中央倉庫。折騰了一天,踩了不少坑才成功的。但願本篇對你們有所幫助。git

項目構建工具:Gradle,版本:6.2.2,官方文檔當前最新版本。本來是使用gradle4.5.1版本的,可是找不到4.5版本的MavenPublication的文檔,倒不如直接將Gradle切換到6.2.2版本。關於MavenPublication看到後面你就知道了。github

首先是到https://issues.sonatype.org/註冊帳號,註冊成功後登錄。須要注意的一點是,帳號的密碼必需要包含大寫字母、小寫字母、數字加特殊符號。登錄成功後,首次登錄會讓你選擇語言,能夠選擇中文,很是友好。redis

若是選擇的是中文,那麼下一步就是在首頁點擊「新建」,能夠理解爲工單,或者英文叫issue,或者能夠理解爲新建項目。在彈出窗口填寫issue信息。shell

項目選擇Community Support - Open Source Project Repository Hosting,問題類型選擇New Project。概要隨便填,描述寫項目的介紹。最後就是填寫Group Id、項目地址、git倉庫地址。數據庫

這裏Group Id我使用個人gitbub的地址。若是是填寫你本身的域名,是須要驗證的,如com.wujiuye,那麼後面須要證實這個域名是你的,怎麼證實後面提到。填寫github的域名也是須要驗證的,下一步介紹。apache

填寫完以後點擊右下角的新建按鈕便可建立項目。ubuntu

在項目建立成功後,你註冊時填寫的郵箱會收到一封郵件,你能夠經過查看郵件看下一步要作說明,或者你也能夠直接在項目詳情頁的底部「註釋」欄看評論,此時會有一個評論,與郵件收到的內容是同樣的。意思是須要你在你的github上建立一個名爲OSSRH-56052的項目。windows

若是你在建立項目時,填寫的Group Id是你本身的域名,這時就會要求你配置DNS來驗證這個域名是你的,或者其它方式,這個我沒去試,具體怎麼驗證我也不清楚。

在你的github上建立完項目以後,還須要回到sonatype網站的項目詳情頁面,在「註釋」下面回覆說你已經完成這一步了。

稍等一會以後,你會收到它的新回覆。

意思是如今你能夠將SNAPSHOTRELEASE的構件(jar)部署到倉庫xxx了。如今回到你的項目,在build.gradle配置文件下,添加配置,使用maven-publish插件將項目打包發佈到倉庫。

這裏參考了gradle官方文檔給的配置:https://docs.gradle.org/current/javadoc/org/gradle/api/publish/maven/MavenPublication.html

先添加maven-publish插件

plugins {
    id 'java'
    // maven 發佈插件
    id 'maven-publish'
}
複製代碼

group改成你在sonatype建立的項目的Group Id。咱們先簡單配置看下是否可以發佈成功,因此先發佈一個SNAPSHOT版本,須要在版本名後面加上-SNAPSHOT,不然發佈到SNAPSHOT倉庫會失敗。

group 'com.github.wujiuye'
version '1.0.0-SNAPSHOT'
複製代碼

注意,以-SNAPSHOT結尾的版本號發佈到release倉庫會失敗,只能發到snapshot倉庫,因此後面發佈release版本時,須要去掉-SNAPSHOT

接着是publishing的配置。

publishing {
    publications {
        // 推送配置
        publishMyProjectMiniexcel(MavenPublication) {
            // 編譯jar包
            from components.java
            // 打包源碼
            artifact sourcesJar
        }
    }
    // 到 https://oss.sonatype.org/#nexus-search; 搜索是否上傳成功
    repositories {
    }
}
複製代碼

repositories詳細配置如圖:

詳細的build.gradle後文會給出。這裏配置兩個倉庫,一個是Release倉庫,一個是Snapshot,名稱name是本身隨便填的,url就是上一步在sonatype你的項目詳情頁收到的回覆的兩個地址。credentials配置的是你登錄sonatype的帳號和密碼。在你項目的build.gradle同級目錄下,新建一個gradle.properties文件,將帳號密碼寫在這個配置文件中。

注意,不要把這個文件提交到github,否則你密碼就泄漏了。最好是在你安裝的gradle的全局gradle.properties文件中配置,這也是推薦的作法。

如何作到安全(這一步能夠先忽略,等後面測試發佈成功了,再回來完成這個步驟):

  • 把用戶名和密碼的配置移動到GRADLE_USER_HOME目錄下的gradle.properties文件中;
  • 項目目錄下的gradle.properties中相同的變量則會覆蓋GRADLE_USER_HOME/gradle.properties中的配置。在執行build的時候,用戶名和密碼會被讀取,若是不存在的話會報錯,好比別人下載了你的源碼調試,將不能構建成功,因此項目目錄下的gradle.properties中保留用戶名和密碼而且是錯誤的用戶名和密碼;
  • 在打包構建的時候,手動去除掉項目中gradle.properties的用戶名和密碼配置。讓構建的時候獲取GRADLE_USER_HOME/gradle.properties中的配置,構建完成後,再還原回來,防止別人構建失敗。

如今就能夠在idea中點擊右側的gradle,也就是前面一張圖的紅色箭頭指向(配置倉庫的那張)。在任務下的publishing選擇publish+你配置的推送任務名稱+PublicationToSnapshotRepository任務執行。

推送成功後到https://oss.sonatype.org/#nexus-search搜索,看看是否是發佈成功了。

如今咱們須要完善配置,發佈Release版本到Release倉庫。咱們先只是修改下版本後,去掉-SNAPSHOT,而後執行publish+你配置的推送任務名稱+PublicationToReleaseRepository任務。注意,與發佈快照版本不是同一個任務,仔細看區別。

而後到https://oss.sonatype.org/#stagingRepositories查看發佈好的構件。點擊左側的Staging Repositories,第一個就是剛剛發佈的jar,此時的構件狀態爲Open

選中構件,並點擊上方的Close,而後會提示你是否確認,繼續點擊Confirm

點擊Refresh,在下邊的Activity選項卡中查看狀態。不出意外,是不會成功的!由於這纔是填坑的開始。

上圖中,當前此次close的狀態,有不少項是驗證失敗的,就是圖標打個叉叉的。

失敗的選項有:

  • POM驗證失敗,緣由是沒有配置POM信息
  • Javadoc驗證失敗,緣由是沒有上傳Javadoc
  • Signature簽名驗證失敗,這個就比較複雜了。

咱們先解決pomjavadoc驗證失敗的問題。回到項目中,在build.gradle文件完善配置,以下:

plugins {
    id 'java'
    // maven 發佈插件
    id 'maven-publish'
}

group 'com.github.wujiuye'
version '1.1.0-RELEASE'

repositories {
    mavenCentral()
}

dependencies {
    // excel表格
    compile group: 'org.apache.poi', name: 'poi', version: '3.17'
    compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
    compile group: 'org.apache.poi', name: 'poi-ooxml-schemas', version: '3.17'

    testCompile group: 'junit', name: 'junit', version: '4.12'
}

// 打包源碼
task sourcesJar(type: Jar) {
    classifier = 'sources'
    from sourceSets.main.allJava
}

// 生成 javadoc jar
task javadocJar(type: Jar) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}

publishing {
    publications {
        // 推送
        publishMyProjectMiniexcel(MavenPublication) {
            // 編譯jar包
            from components.java
            // 打包源碼
            artifact sourcesJar
            // javadoc
            artifact javadocJar

            pom {
                name = "miniexcel"
                description = "基於poi封裝的一套excel文件讀寫工具,完美解決oom問題。優雅的使用設計模式提供更簡單的使用姿式!更有詳細的使用教程。如需獲取幫助,關注微信公衆號:Java藝術"
                url = "https://github.com/wujiuye/miniexcel"
                licenses {
                    license {
                        name = "The Apache License, Version 2.0"
                        url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
                    }
                }
                developers {
                    developer {
                        id = "wujiuye"
                        name = "wujiuye"
                        email = "419611821@qq.com"
                    }
                }
                scm {
                    connection = "scm:git:https://github.com/wujiuye/miniexcel.git"
                    developerConnection = "scm:git:https://github.com/wujiuye/miniexcel.git"
                    url = "https://github.com/wujiuye/miniexcel"
                }
            }
        }
    }
    // 到 https://oss.sonatype.org/#nexus-search; 搜索是否上傳成功
    repositories {
        // 發佈Release版本可在版本號後面帶上'-RELEASE',也可不帶
        maven {
            name 'Release'
            url 'https://oss.sonatype.org/service/local/staging/deploy/maven2'
            credentials {
                username = "${NEXUS_USERNAME}"
                password = "${NEXUS_PASSWORD}"
            }
        }
        // 發佈Snapshot快照版本必須在版本號後面加上'-SNAPSHOT'
        maven {
            name = 'Snapshot'
            url = 'https://oss.sonatype.org/content/repositories/snapshots'
            credentials {
                username = "${NEXUS_USERNAME}"
                password = "${NEXUS_PASSWORD}"
            }
        }
    }
}
複製代碼

如今從新執行一遍publish+你配置的推送任務名稱+PublicationToReleaseRepository任務,再回到https://oss.sonatype.org/#stagingRepositories。因爲前面有提交過,如今刷新會有兩個構件,看最後一個,或者看時間,選擇最新上傳的那個構件,繼續完成Close步驟。

此次已經少了兩個錯誤了,只剩一個簽名驗證失敗。而這個相對來講比較複雜。

咱們須要使用gpg生成密鑰,以個人電腦爲例,mac下安裝gpg很是簡單,使用brew安裝就能夠了。windows下更容易了,一大堆教程,mac下的教程還比較難找。

brew install gpg
複製代碼

使用gpg --gen-key命令生成密鑰。

MacBook-Pro:~ wjy$ gpg --gen-key
gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

注意:使用 「gpg --full-generate-key」 以得到一個功能完整的密鑰產生對話框。
GnuPG 須要構建用戶標識以辨認您的密鑰。
真實姓名: wujiuye
電子郵件地址: 419611821@qq.com
.....
複製代碼

填完電子郵箱後會要求輸入密鑰的密碼。

在建立完成後,可使用gpg --list-keys命令查看。

MacBook-Pro:~ wjy$ gpg --list-keys
gpg: 正在檢查信任度數據庫
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深度:0  有效性:  1  已簽名:  0  信任度:0-,0q,0n,0m,0f,1u
gpg: 下次信任度數據庫檢查將於 2022-03-23 進行
/Users/wjy/.gnupg/pubring.kbx
-----------------------------
pub   rsa2048 2020-03-23 [SC] [有效至:2022-03-23]
      5FE36BC89979FABF8D48ADD0B6559088974BA646
uid           [ 絕對 ] wujiuye <419611821@qq.com>
sub   rsa2048 2020-03-23 [E] [有效至:2022-03-23]
複製代碼

build.gradle配置文件添加簽名插件。

plugins {
    id 'java'
    // maven 發佈插件
    id 'maven-publish'
    // 簽名插件
    id 'signing'
}
.......

publishing {
  ....... 
}

// 必須在 publishing 配置以後
signing {
    sign publishing.publications.publishMyProjectMiniexcel
}
複製代碼

而後在gradle.properties文件中添加密鑰項的配置。

### gpg --list-keys --keyid-format short 查出來的
signing.keyId=52FEDB1A
### 建立密鑰時的密碼
signing.password=wujiuye950605
### .gpg文件的路徑
signing.secretKeyRingFile=/Users/wjy/.gnupg/secring.gpg
複製代碼

使用gpg --gen-key命令建立密鑰並無生成secring.gpg文件,如今咱們能夠經過命令gpg --export-secret-keys生成secring.gpg,生成的secring.gpg文件的路徑即是gradle.properties配置文件中signing.secretKeyRingFile這項的值。

gpg --export-secret-keys -o /Users/wjy/.gnupg/secring.gpg
複製代碼

還有一個signing.keyId能夠經過gpg --list-keys --keyid-format short查詢出來。

注意,是紅框中的那個。如今從新執行一遍publish+你配置的推送任務名稱+PublicationToReleaseRepository任務,再回到https://oss.sonatype.org/#stagingRepositories。能夠繼續完成Close步驟了。

若是簽名仍是驗證失敗,失敗信息以下:

failureMessage	No public key: Key with id: (4e999e3952fedb1a) was not able to be located on <a href="http://keyserver.ubuntu.com:11371/">http://keyserver.ubuntu.com:11371/</a>. Upload your public key and try the operation again.
failureMessage	No public key: Key with id: (4e999e3952fedb1a) was not able to be located on <a href="http://keys.openpgp.org:11371/">http://keys.openpgp.org:11371/</a>. Upload your public key and try the operation again.
failureMessage	No public key: Key with id: (4e999e3952fedb1a) was not able to be located on <a href="http://pool.sks-keyservers.net:11371/">http://pool.sks-keyservers.net:11371/</a>. Upload your public key and try the operation again.
複製代碼

說明咱們還須要將密鑰發送到keyserver.ubuntu.com:11371keys.openpgp.org:11371pool.sks-keyservers.net:11371這幾個地址中的其中一個,按照驗證順序,首選第一個。

MacBook-Pro:.gnupg wjy$ gpg --keyserver http://keyserver.ubuntu.com:11371 --send-keys 5FE36BC89979FABF8D48ADD0B6559088974BA646
gpg: 正在發送密鑰 B6559088974BA646 到 http://keyserver.ubuntu.com:11371
複製代碼

如今重試Close就可以成功了。

耐心等待郵件吧,這個過程是須要好久的。我大概等了一個小時,才收到郵件。

郵件中提示說,我還須要選中最後一次Close成功的構件,點擊Release按鈕。繼續返回https://oss.sonatype.org/#stagingRepositories

如今Release按鈕已經變成可點擊了,愉快的點擊發布吧。大概過了二十多分鐘,收到一封郵件。此時已經凌晨一點半了。

意思是說,再過十分鐘,就能夠在maven中央倉庫中搜索到了,不過對於https://search.maven.org這個網站可能還要兩個小時才能搜索到。

成果:

https://search.maven.org/search?q=miniexcel
複製代碼

最後不要忘記了在sonatype上的項目詳情頁回覆下已經完成,通知sonatype的工做人員關閉issue。之後想發佈開源項目到maven,只要Group Id不變,就能夠省略不少步驟了。

參考資料:

【如何將本身的開源項目發佈到Maven中央倉庫】
https://blog.csdn.net/sinat_23290725/article/details/85018092
【Gradle 發佈 JAR 包到 maven 中央倉庫(sonatype )】
https://blog.csdn.net/mr_zhuqiang/article/details/84564256
【gradle簽名插件配置問題】
https://stackoverflow.com/questions/27936119/gradle-uploadarchives-task-unable-to-read-secret-key
【MavenPublication配置參考】
https://docs.gradle.org/current/javadoc/org/gradle/api/publish/maven/MavenPublication.html
複製代碼

後記

在迭代升級版本的時候,Close成功,但點擊Release按鈕,發佈失敗了。報以下異常:

typeId  RepositoryWritePolicy
failureMessage	| Artifact updating: Repository ='releases:Releases' does not allow updating artifact='/com/github/wujiuye/miniexcel/maven-metadata.xml.sha512'
failureMessage	| Artifact updating: Repository ='releases:Releases' does not allow updating artifact='/com/github/wujiuye/miniexcel/maven-metadata.xml.sha256'
複製代碼

意思是不運行更新maven-metadata.xml.sha512maven-metadata.xml.sha256這兩個文件。

後面在sonatype上找到一樣的問題,也是說升級的時候Release失敗,用的Gradle 6.0版本,而後禁掉sha256sha512校驗後就能夠Release成功,且不會影響正常依賴使用。Unable to release staging repository due to maven-metadata.xml.sha512/256 files

可是沒說是怎麼禁用的,而後我就照着這個思路,想找怎麼禁用sha256sha512校驗的方法,找到了這篇。 maven-metadata.xml SHA256 and SHA512 checksums prevent publishing to Nexus

在項目的gradle.properties文件中添加以下配置便可:

### 禁用Gradle 6.x 版本 SHA-256和SHA-512校驗和的發佈
systemProp.org.gradle.internal.publish.checksums.insecure=true
複製代碼

文中的項目地址:https://repo1.maven.org/maven2/com/github/wujiuye/miniexcel/1.1.1-RELEASE/,歡迎使用!

相關文章
相關標籤/搜索