Ivy 发布插件提供了以Apache Ivy格式发布构建工件的能力,通常发布到存储库以供其他构建或项目使用。发布的是由构建创建的一个或多个工件,以及描述工件和工件的依赖项(如果有)的Ivy模块描述符(通常)。ivy.xml

已发布的 Ivy 模块可由 Gradle(请参阅声明依赖项)和其他理解 Ivy 格式的工具使用。您可以在发布概述中了解发布的基础知识。

用法

要使用 Ivy 发布插件,请在构建脚本中包含以下内容:

build.gradle.kts
plugins {
    `ivy-publish`
}
build.gradle
plugins {
    id 'ivy-publish'
}

Ivy 发布插件在名为PublishingExtensionpublishing类型的项目上使用扩展。此扩展提供了命名出版物的容器和命名存储库的容器。 Ivy 发布插件可与IvyPublication出版物和IvyArtifactRepository存储库配合使用。

任务

generateDescriptorFileForPubNamePublication生成IvyDescriptor

为名为PubName 的发布创建 Ivy 描述符文件,填充已知元数据,例如项目名称、项目版本和依赖项。描述符文件的默认位置是build/publications/$pubName/ivy.xml

publishPubNamePublicationToRepoNameRepositoryPublishToIvyRepository

PubName发布发布到名为RepoName 的存储库。如果您的存储库定义没有显式名称,则RepoName将为“Ivy”。

publish

取决于:所有任务publishPubNamePublicationToRepoNameRepository

将所有定义的发布发布到所有定义的存储库的聚合任务。

刊物

该插件提供IvyPublication类型的出版物。要了解如何定义和使用发布,请参阅基本发布部分。

您可以在 Ivy 出版物中配置四个主要内容:

您可以在完整的发布示例中看到所有这些操作。 API 文档IvyPublication有额外的代码示例。

已发布项目的标识值

生成的ivy模块描述符文件包含<info>标识模块的元素。默认标识值源自以下内容:

覆盖默认标识值很简单:只需在配置IvyPublicationorganisation时指定,module或属性。并且可以通过属性进行设置- 请参阅IvyModuleDescriptorSpecrevisionstatusbranchdescriptor

descriptor属性还可用于添加其他自定义元素作为<info>元素的子元素,如下所示:

build.gradle.kts
publishing {
    publications {
        create<IvyPublication>("ivy") {
            organisation = "org.gradle.sample"
            module = "project1-sample"
            revision = "1.1"
            descriptor.status = "milestone"
            descriptor.branch = "testing"
            descriptor.extraInfo("http://my.namespace", "myElement", "Some value")

            from(components["java"])
        }
    }
}
build.gradle
publishing {
    publications {
        ivy(IvyPublication) {
            organisation = 'org.gradle.sample'
            module = 'project1-sample'
            revision = '1.1'
            descriptor.status = 'milestone'
            descriptor.branch = 'testing'
            descriptor.extraInfo 'http://my.namespace', 'myElement', 'Some value'

            from components.java
        }
    }
}
某些存储库无法处理所有支持的字符。例如,:在发布到 Windows 上文件系统支持的存储库时,该字符不能用作标识符。

Gradle 将处理organisationmodulerevision(以及工件的nameextensionclassifier)的任何有效 Unicode 字符。唯一明确禁止的值是\,/和任何 ISO 控制字符。所提供的值在发布过程中会尽早得到验证。

自定义生成的模块描述符

有时,从项目信息生成的模块描述符文件在发布之前需要进行调整。 Ivy Publish Plugin 为此提供了 DSL。请参阅DSL 参考中的IvyModuleDescriptorSpec以获取可用属性和方法的完整文档。

以下示例展示了如何使用 DSL 最常见的方面:

build.gradle.kts
publications {
    create<IvyPublication>("ivyCustom") {
        descriptor {
            license {
                name = "The Apache License, Version 2.0"
                url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
            }
            author {
                name = "Jane Doe"
                url = "http://example.com/users/jane"
            }
            description {
                text = "A concise description of my library"
                homepage = "http://www.example.com/library"
            }
        }
        versionMapping {
            usage("java-api") {
                fromResolutionOf("runtimeClasspath")
            }
            usage("java-runtime") {
                fromResolutionResult()
            }
        }
    }
}
build.gradle
publications {
    ivyCustom(IvyPublication) {
        descriptor {
            license {
                name = 'The Apache License, Version 2.0'
                url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
            }
            author {
                name = 'Jane Doe'
                url = 'http://example.com/users/jane'
            }
            description {
                text = 'A concise description of my library'
                homepage = 'http://www.example.com/library'
            }
        }
        versionMapping {
            usage('java-api') {
                fromResolutionOf('runtimeClasspath')
            }
            usage('java-runtime') {
                fromResolutionResult()
            }
        }
    }
}

在此示例中,我们只是将“描述”元素添加到生成的 Ivy 依赖项描述符中,但此挂钩允许您修改生成的描述符的任何方面。例如,您可以将依赖项的版本范围替换为用于生成构建的实际版本。

您还可以通过IvyModuleDescriptorSpec.withXml(org.gradle.api.Action)将任意 XML 添加到描述符文件,但不能使用它来修改模块标识符的任何部分(组织、模块、修订)。

有可能修改描述符使其不再是有效的 Ivy 模块描述符,因此使用此功能时必须小心。

自定义依赖版本

支持两种发布依赖关系的策略:

声明的版本(默认)

此策略发布由构建脚本作者使用块中的依赖项声明定义的版本dependencies。发布时不会考虑任何其他类型的处理,例如通过更改已解析版本的规则。

已解决的版本

该策略可能通过应用解决规则和自动冲突解决来发布在构建期间解决的版本。这样做的优点是发布的版本与测试发布的工件的版本相对应。

已解决版本的示例用例:

  • 项目使用动态版本作为依赖项,但更喜欢向其使用者公开给定版本的已解析版本。

  • 结合依赖锁定,您希望发布锁定的版本。

  • 一个项目利用了 Gradle 的丰富版本约束,它对 Ivy 进行了有损转换。它不依赖转换,而是发布已解析的版本。

这是通过使用versionMappingDSL 方法来完成的,该方法允许配置VersionMappingStrategy

build.gradle.kts
publications {
    create<IvyPublication>("ivyCustom") {
        versionMapping {
            usage("java-api") {
                fromResolutionOf("runtimeClasspath")
            }
            usage("java-runtime") {
                fromResolutionResult()
            }
        }
    }
}
build.gradle
publications {
    ivyCustom(IvyPublication) {
        versionMapping {
            usage('java-api') {
                fromResolutionOf('runtimeClasspath')
            }
            usage('java-runtime') {
                fromResolutionResult()
            }
        }
    }
}

runtimeClasspath在上面的示例中,Gradle 将使用在 中声明的依赖项上解析的版本api,这些版本映射到compileIvy 的配置。 Gradle 还将使用runtimeClasspath在 中声明的依赖项上解析的版本implementation,这些版本映射到runtimeIvy 的配置。 fromResolutionResult()指示 Gradle 应该使用变体的默认类路径,并且runtimeClasspathjava-runtime.

存储库

该插件提供IvyArtifactRepository类型的存储库。要了解如何定义和使用存储库进行发布,请参阅基本发布部分。

这是定义发布存储库的简单示例:

build.gradle.kts
publishing {
    repositories {
        ivy {
            // change to point to your repo, e.g. http://my.org/repo
            url = uri(layout.buildDirectory.dir("repo"))
        }
    }
}
build.gradle
publishing {
    repositories {
        ivy {
            // change to point to your repo, e.g. http://my.org/repo
            url = layout.buildDirectory.dir("repo")
        }
    }
}

您需要配置的两个主要内容是存储库的:

  • 网址(必填)

  • 姓名(可选)

您可以定义多个存储库,只要它们在构建脚本中具有唯一的名称即可。您还可以声明一个(且仅有一个)没有名称的存储库。该存储库将采用隐式名称“Ivy”。

您还可以配置连接到存储库所需的任何身份验证详细信息。有关更多详细信息,请参阅IvyArtifactRepository 。

完整示例

以下示例演示了使用多项目构建进行发布。每个项目都会发布一个 Java 组件,该组件配置为构建和发布 Javadoc 和源代码工件。描述符文件经过定制以包含每个项目的项目描述。

settings.gradle.kts
rootProject.name = "ivy-publish-java"
include("project1", "project2")
buildSrc/build.gradle.kts
plugins {
    `kotlin-dsl`
}

repositories {
    gradlePluginPortal()
}
buildSrc/src/main/kotlin/myproject.publishing-conventions.gradle.kts
plugins {
    id("java-library")
    id("ivy-publish")
}

version = "1.0"
group = "org.gradle.sample"

repositories {
    mavenCentral()
}

java {
    withJavadocJar()
    withSourcesJar()
}

publishing {
    repositories {
        ivy {
            // change to point to your repo, e.g. http://my.org/repo
            url = uri("${rootProject.buildDir}/repo")
        }
    }
    publications {
        create<IvyPublication>("ivy") {
            from(components["java"])
            descriptor.description {
                text = providers.provider({ description })
            }
        }
    }
}
project1/build.gradle.kts
plugins {
    id("myproject.publishing-conventions")
}

description = "The first project"

dependencies {
    implementation("junit:junit:4.13")
    implementation(project(":project2"))
}
project2/build.gradle.kts
plugins {
    id("myproject.publishing-conventions")
}

description = "The second project"

dependencies {
    implementation("commons-collections:commons-collections:3.2.2")
}
settings.gradle
rootProject.name = 'ivy-publish-java'
include 'project1', 'project2'
buildSrc/build.gradle
plugins {
    id 'groovy-gradle-plugin'
}
buildSrc/src/main/groovy/myproject.publishing-conventions.gradle
plugins {
    id 'java-library'
    id 'ivy-publish'
}

version = '1.0'
group = 'org.gradle.sample'

repositories {
    mavenCentral()
}

java {
    withJavadocJar()
    withSourcesJar()
}

publishing {
    repositories {
        ivy {
            // change to point to your repo, e.g. http://my.org/repo
            url = "${rootProject.buildDir}/repo"
        }
    }
    publications {
        ivy(IvyPublication) {
            from components.java
            descriptor.description {
                text = providers.provider({ description })
            }
        }
    }
}
project1/build.gradle
plugins {
    id 'myproject.publishing-conventions'
}

description = 'The first project'

dependencies {
    implementation 'junit:junit:4.13'
    implementation project(':project2')
}
project2/build.gradle
plugins {
    id 'myproject.publishing-conventions'
}

description = 'The second project'

dependencies {
    implementation 'commons-collections:commons-collections:3.2.2'
}

结果是每个项目都会发布以下工件:

  • Gradle 模块元数据文件:project1-1.0.module.

  • Ivy 模块元数据文件:ivy-1.0.xml.

  • Java 组件的主要 JAR 工件:project1-1.0.jar.

  • Java 组件的 Javadoc 和源 JAR 工件(因为我们配置了withJavadocJar()withSourcesJar()):project1-1.0-javadoc.jar, project1-1.0-source.jar