絕大多數的軟體專案建置的目標都是以某種方式被使用。它可以是其他軟體專案使用的函式庫,或是提供給最終使用者的應用程式。發布 是指建置的成果以某種方式提供給使用者存取的過程。

在 Gradle 中,這個過程如下

  1. 定義 發布什麼

  2. 定義 發布到哪裡

  3. 執行 發布

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

從 Gradle 6.0 開始,Gradle 模組元資料 將會永遠與 Ivy XML 或 Maven POM 元資料檔案一起發布。

Gradle 提供 Maven 發布外掛Ivy 發布外掛 等預先封裝好的基礎架構,讓您能輕鬆發布到這些類型的儲存庫。這些外掛讓您能設定要發布的內容,並在最少的工作量下執行發布。

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 外掛會定義 components.java SoftwareComponent,而 War 外掛會定義 components.web

此範例也會定義一個名為「myRepo」的基於檔案的 Maven 儲存庫。此類型的基於檔案的儲存庫很適合範例,但實際建置通常會使用基於 HTTPS 的儲存庫伺服器,例如 Maven Central 或內部公司伺服器。

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

出版品和儲存庫定義會與專案的 groupversion 結合,提供 Gradle 發布專案生產 JAR 所需的一切。然後,Gradle 會建立一個專用的 publishMyLibraryPublicationToMyRepoRepository 工作來執行此動作。其名稱是根據範本 publishPubNamePublicationToRepoNameRepository 建立。請參閱適當的發布外掛文件,以取得有關此工作性質和您可能可用的任何其他工作的詳細資料。

您可以直接執行個別的發佈工作,或執行 publish,它會執行所有可用的發佈工作。在此範例中,publish 只會執行 publishMyLibraryPublicationToMavenRepository

對 Ivy 儲存庫的基本發佈非常類似:您只需使用 Ivy 發佈外掛,將 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')
}