绝大多数软件项目构建的东西旨在以某种方式被使用。它可以是其他软件项目使用的库,也可以是最终用户的应用程序。 发布是将正在构建的东西提供给消费者的过程。

在 Gradle 中,该过程如下所示:

  1. 定义要发布的内容

  2. 定义发布到的位置

  3. 进行出版

其中每个步骤都取决于您要将工件发布到的存储库的类型。最常见的两种类型是 Maven 兼容和 Ivy 兼容存储库,简称 Maven 和 Ivy 存储库。

从 Gradle 6.0 开始,Gradle 模块元数据将始终与 Ivy XML 或 Maven POM 元数据文件一起发布。

Gradle 通过以Maven Publish PluginIvy Publish Plugin的形式提供一些预打包的基础设施,使发布到这些类型的存储库变得容易。这些插件允许您配置要发布的内容并以最少的努力执行发布。

出版流程
图 1. 发布流程

让我们更详细地看看这些步骤:

发布什么

Gradle 需要知道要发布哪些文件和信息,以便消费者可以使用您的项目。这通常是工件和元数据的组合,Gradle 称之为发布。出版物所包含的具体内容取决于其发布到的存储库的类型。

例如,发往 Maven 存储库的出版物包括:

  • 一个或多个工件 - 通常由项目构建,

  • Gradle 模块元数据文件将描述已发布组件的变体,

  • Maven POM 文件将识别主要工件及其依赖项。主要工件通常是项目的生产 JAR,次要工件可能由“-sources”和“-javadoc”JAR 组成。

此外,Gradle 将发布上述所有内容的校验和,以及配置后的签名。从 Gradle 6.0 开始,这包括校验SHA256和。SHA512

发布地点

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 存储库。我们使用以下块来实现这一点,该块由PublishingExtensionpublishing {}支持:

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”。所有其他存储库定义必须给出明确的名称。

与项目的group和相结合version,发布和存储库定义提供了 Gradle 发布项目的生产 JAR 所需的一切。然后 Gradle 将创建一个专用publishMyLibraryPublicationToMyRepoRepository任务来完成此任务。它的名称是基于模板的。有关此任务的性质以及您可能可以使用的任何其他任务的更多详细信息,请参阅相应的发布插件的文档。publishPubNamePublicationToRepoNameRepository

您可以直接执行各个发布任务,也可以执行publish,这将运行所有可用的发布任务。在此示例中,publish将仅运行publishMyLibraryPublicationToMavenRepository.

到 Ivy 存储库的基本发布非常相似:您只需使用 Ivy 发布插件,替换MavenPublicationIvyPublication,并在存储库定义中使用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')
}