Sonatype 提供了一個叫作開源軟件資源庫託管Open Source Software Repository Hosting (OSSRH) 的工具,幫助咱們來方便的將項目發佈到中心倉庫中。java
可是這個工具和咱們的項目構建是割裂的,尤爲是在CI集成構建中,很難作到自動化。git
Gradle是一個很好的構建工具,靈活而又強大,可不能夠直接在Gradle中的任務中直接構建和上傳到中央倉庫或者其餘自定義的nexus倉庫中呢?答案是確定的。github
今天要給你們介紹的gradle插件名字叫作Gradle Nexus Publish Plugin,最近才發佈了1.0.0版本,有小夥伴可能要問了,gradle出來這麼久了,最近纔有這樣的插件嗎?api
其實否則,咱們來說一下gradle Nexus發佈插件的歷史。網絡
2015年,Marcin Zajączkowski建立了gradle-nexus-staging-plugin,該插件可在Nexus存儲庫管理器中關閉和釋放staging存儲庫。使用這個插件就能夠直接從代碼中將Gradle項目發佈到Maven Central倉庫。多年來,它已經在全球各地被多個項目所採用。架構
可是這個插件存在一個小問題: 因爲Gradle發佈過程當中的技術限制,所以須要使用啓發式技術來跟蹤隱式建立的staging存儲庫,對於給定狀態的多個存儲庫,一般會發布失敗。尤爲是在持續集成服務Travis CI在2019年底更改其網絡架構以後,這個插件問題就更多了。併發
基於這個問題,馬克·菲利普(Marc Philipp)建立了另一個插件Nexus Publish Plugin,該插件豐富了Gradle中的發佈機制,能夠顯式建立staging存儲庫並直接向其發佈(上傳)組件。maven
一般咱們須要將這兩個插件一塊兒使用,可是,一個功能須要使用到兩個插件仍是會讓用戶感到困惑。因此Gradle Nexus Publish Plugin在2020/2021年應運而生了,它的目的就是合併上面兩個插件的功能。工具
在gradle中使用該插件很簡單,首先須要引入這個插件:gradle
plugins { id("io.github.gradle-nexus.publish-plugin") version "«version»" }
注意,這個插件必須在 Gradle 5.0 或者以後的版本使用,而且在根項目中引入。
接下來,咱們須要定義要發佈的倉庫,若是是經過Sonatype's OSSRH Nexus發佈到Maven的中央倉庫,那麼須要添加sonatype(),以下所示:
nexusPublishing { repositories { sonatype() } }
在sonatype()中,實際上定義了nexusUrl 和 snapshotRepositoryUrl。
發佈到中央倉庫是須要用戶名密碼的,咱們須要設置sonatypeUsername 和 sonatypePassword 這兩個項目的屬性。一種方法是在~/.gradle/gradle.properties 中進行配置,或者設置 ORG_GRADLE_PROJECT_sonatypeUsername 和 ORG_GRADLE_PROJECT_sonatypePassword 這兩個環境變量。
或者,能夠直接在sonatype 中進行定義:
nexusPublishing { repositories { sonatype { username = "your-username" password = "your-password" } } }
最後,調用publishToSonatype和 closeAndReleaseSonatypeStagingRepository就能夠分別發佈到Sonatype和關閉併發布到中央倉庫了。
注意,上面的closeAndReleaseSonatypeStagingRepository其實是包含了兩步操做:close和release。咱們也能夠僅僅調用closeSonatypeStagingRepository,而後手動登陸Nexus UI,進行release操做。
下面是兩個分別使用groovy和Kotlin的具體的例子:
plugins { id "java-library" id "maven-publish" id "io.github.gradle-nexus.publish-plugin" version "«version»" } publishing { publications { mavenJava(MavenPublication) { from(components.java) } } } nexusPublishing { repositories { myNexus { nexusUrl = uri("https://your-server.com/staging") snapshotRepositoryUrl = uri("https://your-server.com/snapshots") username = "your-username" // defaults to project.properties["myNexusUsername"] password = "your-password" // defaults to project.properties["myNexusPassword"] } } }
plugins { `java-library` `maven-publish` id("io.github.gradle-nexus.publish-plugin") version "«version»" } publishing { publications { create<MavenPublication>("mavenJava") { from(components["java"]) } } } nexusPublishing { repositories { create("myNexus") { nexusUrl.set(uri("https://your-server.com/staging")) snapshotRepositoryUrl.set(uri("https://your-server.com/snapshots")) username.set("your-username") // defaults to project.properties["myNexusUsername"] password.set("your-password") // defaults to project.properties["myNexusPassword"] } } }
默認狀況下nexusPublishing中的connectTimeout和clientTimeout是5分鐘,能夠根據本身的須要進行調整。
咱們來看一下這個插件背後是怎麼工做的。
首先定義的nexusPublishing { repositories { ... } }
會攔截全部子項目的 maven-publish
插件,用來修改發佈地址。
若是項目的版本號不是以-SNAPSHOT
結尾,這說明是發佈版本,那麼會建立一個initialize${repository.name.capitalize()}StagingRepository
任務,開啓一個新的staging倉庫,而且設置好對應的URL。在多項目構建中,全部擁有相同nexusUrl 的子項目,將會使用一樣的staging倉庫。
initialize${repository.name.capitalize()}StagingRepository
爲每一個配置好的倉庫地址,生成發佈任務。
爲每一個發佈任務生成一個 publishTo${repository.name.capitalize()}
生命週期task。
在發佈任務以後分別建立 close${repository.name.capitalize()}StagingRepository
和 release${repository.name.capitalize()}StagingRepository
任務。
這麼好用的插件,趕忙去試試吧。
本文已收錄於 http://www.flydean.com/07-gradle-nexus-publish-plugin/
最通俗的解讀,最深入的乾貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!
歡迎關注個人公衆號:「程序那些事」,懂技術,更懂你!