絕大多數的軟體專案都會建置一些旨在以某種方式被使用的東西。它可能是一個其他軟體專案使用的函式庫,或者它可能是最終使用者的應用程式。發佈是將正在建置的東西提供給使用者的過程。

在 Gradle 中,該過程如下所示

  1. 定義要發佈的內容

  2. 定義發佈到何處

  3. 執行發佈

這些步驟中的每一個都取決於您要將成品發佈到的儲存庫類型。最常見的兩種類型是相容 Maven 和相容 Ivy 的儲存庫,或簡稱 Maven 和 Ivy 儲存庫。

從 Gradle 6.0 開始,Gradle 模組中繼資料將始終與 Ivy XML 或 Maven POM 中繼資料檔案一起發佈。

Gradle 透過以 Maven Publish PluginIvy Publish Plugin 的形式提供一些預先封裝的基礎架構,可以輕鬆發佈到這些類型的儲存庫。這些外掛程式可讓您配置要發佈的內容,並以最少的精力執行發佈。

publishing process
圖 1. 發佈過程

讓我們更詳細地看看這些步驟

要發佈什麼

Gradle 需要知道要發佈哪些檔案和資訊,以便使用者可以使用您的專案。這通常是成品和中繼資料的組合,Gradle 稱之為發佈。發佈的確切內容取決於要發佈到的儲存庫類型。

例如,目標為 Maven 儲存庫的發佈包括

  • 一個或多個成品 — 通常由專案建置,

  • Gradle 模組中繼資料檔案,它將描述已發佈組件的變體,

  • Maven POM 檔案將識別主要成品及其相依性。主要成品通常是專案的生產 JAR,而次要成品可能包含「-sources」和「-javadoc」JAR。

此外,Gradle 將發佈上述所有項目的校驗和,以及配置為執行此操作時的簽名。從 Gradle 6.0 開始,這包括 SHA256SHA512 校驗和。

發佈到何處

Gradle 需要知道將成品發佈到何處,以便使用者可以取得它們。這是透過儲存庫完成的,儲存庫儲存並提供各種成品。Gradle 也需要與儲存庫互動,這就是為什麼您必須提供儲存庫的類型及其位置。

如何發佈

Gradle 會自動為發佈和儲存庫的所有可能組合產生發佈任務,讓您可以將任何成品發佈到任何儲存庫。如果您要發佈到 Maven 儲存庫,則任務類型為 PublishToMavenRepository,而對於 Ivy 儲存庫,任務類型為 PublishToIvyRepository

接下來是一個實際範例,示範整個發佈過程。

設定基本發佈

發佈的第一步,無論您的專案類型為何,都是套用適當的發佈外掛程式。如簡介中所述,Gradle 透過以下外掛程式支援 Maven 和 Ivy 儲存庫

這些外掛程式提供配置對應儲存庫類型發佈所需的特定發佈和儲存庫類別。由於 Maven 儲存庫是最常用的儲存庫,因此它們將成為此範例和本章中其他範例的基礎。別擔心,我們將說明如何調整個別範例以用於 Ivy 儲存庫。

假設我們正在處理一個簡單的 Java 函式庫專案,因此僅套用了以下外掛程式

build.gradle.kts
plugins {
    `java-library`
    `maven-publish`
}
build.gradle
plugins {
    id 'java-library'
    id 'maven-publish'
}

套用適當的外掛程式後,您可以配置發佈和儲存庫。在此範例中,我們想要將專案的生產 JAR 檔案(由 jar 任務產生的檔案)發佈到自訂 Maven 儲存庫。我們使用以下 publishing {} 區塊來執行此操作,該區塊由 PublishingExtension 支援

build.gradle.kts
group = "org.example"
version = "1.0"

publishing {
    publications {
        create<MavenPublication>("myLibrary") {
            from(components["java"])
        }
    }

    repositories {
        maven {
            name = "myRepo"
            url = uri(layout.buildDirectory.dir("repo"))
        }
    }
}
build.gradle
group = 'org.example'
version = '1.0'

publishing {
    publications {
        myLibrary(MavenPublication) {
            from components.java
        }
    }

    repositories {
        maven {
            name = 'myRepo'
            url = layout.buildDirectory.dir("repo")
        }
    }
}

這定義了一個名為「myLibrary」的發佈,由於其類型:MavenPublication,可以發佈到 Maven 儲存庫。此發佈僅包含生產 JAR 成品及其中繼資料,兩者組合由專案的 java 組件表示。

組件是定義發佈的標準方式。它們由外掛程式提供,通常是語言或平台類型。例如,Java Plugin 定義了 components.java SoftwareComponent,而 War Plugin 定義了 components.web

範例也定義了一個名為「myRepo」的基於檔案的 Maven 儲存庫。這種基於檔案的儲存庫對於範例很方便,但實際建置通常與基於 HTTPS 的儲存庫伺服器(例如 Maven Central 或內部公司伺服器)一起使用。

您可以定義一個且僅一個沒有名稱的儲存庫。這轉換為 Maven 儲存庫的隱式名稱「Maven」和 Ivy 儲存庫的「Ivy」。所有其他儲存庫定義都必須給定明確的名稱。

結合專案的 groupversion,發佈和儲存庫定義提供了 Gradle 發佈專案生產 JAR 所需的一切。然後,Gradle 將建立一個專用的 publishMyLibraryPublicationToMyRepoRepository 任務來執行此操作。其名稱基於範本 publishPubNamePublicationToRepoNameRepository。有關此任務的性質以及可能提供給您的任何其他任務的更多詳細資訊,請參閱適當的發佈外掛程式的文件。

您可以直接執行個別發佈任務,也可以執行 publish,這將執行所有可用的發佈任務。在此範例中,publish 將僅執行 publishMyLibraryPublicationToMavenRepository

基本發佈到 Ivy 儲存庫非常相似:您只需使用 Ivy Publish Plugin,將 MavenPublication 替換為 IvyPublication,並在儲存庫定義中使用 ivy 而不是 maven

兩種儲存庫類型之間存在差異,特別是關於每種儲存庫支援的額外中繼資料 — 例如,Maven 儲存庫需要 POM 檔案,而 Ivy 儲存庫有自己的中繼資料格式 — 因此請參閱外掛程式章節,以取得有關如何為您正在使用的任何儲存庫類型配置發佈和儲存庫的全面資訊。

這就是基本用例的全部內容。但是,許多專案需要更多地控制發佈的內容,因此我們將在以下章節中查看幾個常見情境。

抑制驗證錯誤

Gradle 執行產生的模組中繼資料的驗證。在某些情況下,驗證可能會失敗,表示您很可能有一個錯誤需要修復,但您可能是有意這樣做的。如果是這種情況,Gradle 將指示您可以在 GenerateModuleMetadata 任務上停用的驗證錯誤名稱

build.gradle.kts
tasks.withType<GenerateModuleMetadata> {
    // The value 'enforced-platform' is provided in the validation
    // error message you got
    suppressedValidationErrors.add("enforced-platform")
}
build.gradle
tasks.withType(GenerateModuleMetadata).configureEach {
    // The value 'enforced-platform' is provided in the validation
    // error message you got
    suppressedValidationErrors.add('enforced-platform')
}