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

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

Usage

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

例子1.应用Ivy Publish插件
build.gradle
plugins {
    id 'ivy-publish'
}
build.gradle.kts
plugins {
    `ivy-publish`
}

常春藤发布插件使用命名的项目延期publishing类型的PublishingExtension . 此扩展提供了一个命名出版物的容器和一个命名存储库的容器. Ivy Publish插件可与IvyPublication出版物和IvyArtifactRepository仓库一起使用.

Tasks

generateDescriptorFileForPubNamePublicationGenerateIvyDescriptor

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

publishPubNamePublicationToRepoNameRepositoryPublishToIvyRepository

PubName发布发布到名为RepoName的存储库. 如果您的存储库定义没有明确的名称,则RepoName将为" Ivy".

publish

取决于 :全部publish PubName PublicationTo RepoName Repository任务

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

Publications

此插件提供出版物类型的IvyPublication . 要了解如何定义和使用出版物,请参见" 基本出版 "部分.

您可以在Ivy发布中配置以下四项主要内容:

您可以在完整的发布示例中看到所有这些内容. IvyPublication的API文档包含其他代码示例.

Identity values for the published project

生成的Ivy模块描述符文件包含一个标识模块的<info>元素. 默认标识值从以下派生:

Overriding the default identity values is easy: simply specify the organisation, module or revision properties when configuring the IvyPublication. status and branch can be set via the descriptor property — see IvyModuleDescriptorSpec.

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

例子2.定制发布标识
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
        }
    }
}
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"])
        }
    }
}

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

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

Customizing the generated module descriptor

At times, the module descriptor file generated from the project information will need to be tweaked before publishing. The Ivy Publish Plugin provides a DSL for that purpose. Please see IvyModuleDescriptorSpec in the DSL Reference for the complete documentation of available properties and methods.

下面的示例演示如何使用DSL最常见的方面:

例子3.定制模块描述符文件
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()
                }
            }
        }
    }
build.gradle.kts
    publications {
        create<IvyPublication>("ivyCustom") {
            descriptor {
                license {
                    name.set("The Apache License, Version 2.0")
                    url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
                }
                author {
                    name.set("Jane Doe")
                    url.set("http://example.com/users/jane")
                }
                description {
                    text.set("A concise description of my library")
                    homepage.set("http://www.example.com/library")
                }
            }
            versionMapping {
                usage("java-api") {
                    fromResolutionOf("runtimeClasspath")
                }
                usage("java-runtime") {
                    fromResolutionResult()
                }
            }
        }
    }

在此示例中,我们仅向生成的Ivy依赖项描述符添加了一个'description'元素,但是此钩子允许您修改生成的描述符的任何方面. 例如,您可以将依赖关系的版本范围替换为用于生成内部版本的实际版本.

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

可以以不再是有效的Ivy模块描述符的方式修改描述符,因此在使用此功能时必须小心.

Customizing dependencies versions

支持两种策略来发布依赖项:

Declared versions (default)

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

Resolved versions

此策略可能会通过应用解决方案规则和自动冲突解决方案来发布在构建期间已解决的版本. 这样做的好处是,发布的版本与发布的工件所针对的版本相对应.

解析版本的用例示例:

  • 项目将动态版本用于依赖项,但更喜欢将给定发行版的已解析版本公开给其使用者.

  • 依赖项锁定结合使用,您要发布锁定的版本.

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

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

例子4.使用解析版本
build.gradle
    publications {
        ivyCustom(IvyPublication) {
            versionMapping {
                usage('java-api') {
                    fromResolutionOf('runtimeClasspath')
                }
                usage('java-runtime') {
                    fromResolutionResult()
                }
            }
        }
    }
build.gradle.kts
    publications {
        create<IvyPublication>("ivyCustom") {
            versionMapping {
                usage("java-api") {
                    fromResolutionOf("runtimeClasspath")
                }
                usage("java-runtime") {
                    fromResolutionResult()
                }
            }
        }
    }

在上面的示例中,Gradle将在runtimeClasspath上解析的版本用于api声明的依赖项,这些依赖项映射到Ivy的compile配置. Gradle还将在runtimeClasspath上解析的版本用于在implementation声明的依赖项,这些依赖项映射到Ivy的runtime配置. fromResolutionResult()表示Gradle应该使用变量的默认类路径, runtimeClasspathjava-runtime的默认类路径.

Repositories

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

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

示例5.声明要发布到的存储库
build.gradle
publishing {
    repositories {
        ivy {
            // change to point to your repo, e.g. http://my.org/repo
            url = "$buildDir/repo"
        }
    }
}
build.gradle.kts
publishing {
    repositories {
        ivy {
            // change to point to your repo, e.g. http://my.org/repo
            url = uri("$buildDir/repo")
        }
    }
}

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

  • 网址(必填)

  • 名称(可选)

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

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

Complete example

下面的示例演示了使用多项目构建的发布. 每个项目都发布一个Java组件,该Java组件配置为还构建和发布Javadoc和源代码工件. 定制描述符文件以包括每个项目的项目描述.

例子6.发布一个Java模块
build.gradle
subprojects {
    apply plugin: 'java'
    apply plugin: 'ivy-publish'

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

    repositories {
        mavenCentral()
    }
    java {
        withJavadocJar()
        withSourcesJar()
    }
}

project(':project1') {
    description = 'The first project'

    dependencies {
        implementation 'junit:junit:4.12'
        implementation project(':project2')
    }
}

project(':project2') {
    description = 'The second project'

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

subprojects {
    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 = description
                }
            }
        }
    }
}
build.gradle.kts
subprojects {
    apply(plugin = "java")
    apply(plugin = "ivy-publish")

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

    repositories {
        mavenCentral()
    }
    val java = extensions.getByType<JavaPluginExtension>()
    java.withJavadocJar()
    java.withSourcesJar()
}

project(":project1") {
    description = "The first project"

    dependencies {
        "implementation"("junit:junit:4.12")
        "implementation"(project(":project2"))
    }
}

project(":project2") {
    description = "The second project"

    dependencies {
        "implementation"("commons-collections:commons-collections:3.2.2")
    }
}

subprojects {
    configure<PublishingExtension>() {
        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.set(description)
                }
            }
        }
    }
}

结果是将为每个项目发布以下工件:

  • 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.jarproject1-1.0-source.jar .

Migrating from legacy Ivy publication

如果要迁移以前依赖于旧版发布支持的项目,则会发现以下两种解决方案之间的差异.

Configurations marked as non transitive

当一个配置被标记为transitive = false ,它不会映射到Ivy.

Gradle将发出警告,指出已发布此类配置. 如果确实需要发布此建议,则建议使用依赖项级别transitive = false .

Forced dependencies are not mapped

尽管常春藤支持对依赖项使用force的概念,但Gradle不会将其已弃用的force声明映射到该依赖项 .

相反,建议使用strictly版本替换Gradle force ,该版本提供更好的语义并受Gradle模块元数据格式支持.

注意,如果绝对需要发布强制,则仍然可以修改生成的ivy.xml .