本章内容描述了一个新的 孵化中的 功能,是由“maven-publish
”插件提供的 maven 发布支持。最终这个新的发布支持将取代通过Upload
任务发布的方式。
This chapter describes the new incubating Maven publishing support provided by the “maven-publish
” plugin. Eventually this new publishing support will replace publishing via the Upload
task.
如果你正在查找有关使用 Upload
任务的原始的 Maven 发布支持的文档,请查阅《第五十一章,发布工件》。
If you are looking for documentation on the original Maven publishing support using the Upload
task please see Chapter 51, Publishing artifacts.
本章介绍如何将构建工件发布到 Apache Maven 仓库。发布到 Maven 仓库的模块可以被 Maven、Gradle(参见《第 50 章,依赖管理》)和其他理解 Maven 仓库格式的工具使用。
This chapter describes how to publish build artifacts to an Apache Maven Repository. A module published to a Maven repository can be consumed by Maven, Gradle (see Chapter 50, Dependency Management) and other tools that understand the Maven repository format.
使用Maven格式发布的功能,是由 “maven-publish
” 插件提供的。
The ability to publish in the Maven format is provided by the “maven-publish
” plugin.
“publishing
”项目在“publishing
”项目上创建了一个PublishingExtension
类型的扩展。这个扩展提供了两个容器,一个叫publications,一个叫repositories。“maven-publish
”插件适用于MavenPublication
publications 和 IvyArtifactRepository
repositories。
The “publishing
” plugin creates an extension on the project named “publishing
” of type PublishingExtension
. This extension provides a container of named publications and a container of named repositories. The “maven-publish
” plugin works with MavenPublication
publications and MavenArtifactRepository
repositories.
示例 65.1. 应用“maven-publish”插件 - Example 65.1. Applying the 'maven-publish' plugin
build.gradle
apply plugin: 'maven-publish'
应用“maven-publish
”插件将执行以下操作:
Applying the “maven-publish
” plugin does the following:
publishing
”插件 publishing
” pluginMavenPublication
自动创建一个 GenerateMavenPom
任务(见《第 65.2 节,“发布”》)。 GenerateMavenPom
task for each MavenPublication
added (see Section 65.2, “Publications”).MavenPublication
(见《第 65.2 节,“发布”》)及 MavenArtifactRepository
(见《第 65.3 节, “仓库”》)的组合,自动创建一个 PublishToMavenRepository
任务。 PublishToMavenRepository
task for the combination of each MavenPublication
added (see Section 65.2, “Publications”), with each MavenArtifactRepository
added (see Section 65.3, “Repositories”).MavenPublication
(请参见《第 65.2 节,“发布”》)自动创建一个 PublishToMavenLocal
任务。 PublishToMavenLocal
task for each MavenPublication
added (seeSection 65.2, “Publications”). 如果你不熟悉项目工件和配置,你应该阅读介绍这些概念的《第五十一章,发布工件》。本章还介绍了使用另一种不同的机制的“发布工件 ”。这里描述的发布功能最终会取代那一功能。
If you are not familiar with project artifacts and configurations, you should read the Chapter 51, Publishing artifacts that introduces these concepts. This chapter also describes “publishing artifacts” using a different mechanism than what is described in this chapter. The publishing functionality described here will eventually supersede that functionality.
Publication对象描述了要创建的发布内容的结构和配置。Publications是通过任务发布到仓库的,发布对象的配置明确地决定了要发布的内容。一个项目的所有publications都会在PublishingExtension.getPublications()
容器中定义,每一个publication在项目中都具有唯一名称。
Publication objects describe the structure/configuration of a publication to be created. Publications are published to repositories via tasks, and the configuration of the publication object determines exactly what is published. All of the publications of a project are defined in the PublishingExtension.getPublications()
container. Each publication has a unique name within the project.
要使“maven-publish
”插件起作用,必须将一个 MavenPublication
添加到publications集合里。这个publication决定了实际要发布的工件,以及在关联的POM文件中包含的详细信息。通过添加组件,自定义工件以及修改生成的POM文件,可以配置一个publication。
For the “maven-publish
” plugin to have any effect, a MavenPublication
must be added to the set of publications. This publication determines which artifacts are actually published as well as the details included in the associated POM file. A publication can be configured by adding components, customizing artifacts, and by modifying the generated POM file directly.
将 Gradle 项目发布到 Maven 库的最简单方法是指定一个要发布的 SoftwareComponent
。目前可用于publication的组件有:
The simplest way to publish a Gradle project to a Maven repository is to specify a SoftwareComponent
to publish. The components presently available for publication are:
表65.1. 软件组件 - Table 65.1. Software Components
名称 Name |
提供者 Provided By |
工件 Artifacts |
依赖 Dependencies |
java |
第二十三章. Java 插件 Chapter 23, The Java Plugin |
生成的 jar 文件 Generated jar file |
“runtime”配置的依赖 Dependencies from 'runtime' configuration |
web |
第二十六章. War 插件 Chapter 26, The War Plugin |
生成的 war 文件 Generated war file |
没有依赖 No dependencies |
在以下示例中,工件和运行时依赖都来自由 Java Plugin
添加的 “java” 组件。
In the following example, artifacts and runtime dependencies are taken from the `java` component, which is added by the Java Plugin
.
示例 65.2. 为一个java组件添加一个MavenPublication - Example 65.2. Adding a MavenPublication for a java component
build.gradle
publications { mavenJava(MavenPublication) { from components.java } }
我们还可以显式地配置要被包含在publication的工件。这些工件通常是以原始文件,或者是 AbstractArchiveTask
的实例(如Jar, Zip)的方式来提供。
It is also possible to explicitly configure artifacts to be included in the publication. Artifacts are commonly supplied as raw files, or as instances of AbstractArchiveTask
(e.g. Jar, Zip).
对于每个自定义工件,可以指定用于发布的extension
和classifier
值。请注意,已发布的工件只有一个可以具有空的classifier,其他所有工件必须有一个唯一的classifier/extension组合。
For each custom artifact, it is possible to specify the extension
and classifier
values to use for publication. Note that only one of the published artifacts can have an empty classifier, and all other artifacts must have a unique classifier/extension combination.
如下所示配置自定义工件︰
Configure custom artifacts as follows:
示例65.3. 向MavenPublication 添加其他的工件 - Example 65.3. Adding additional artifact to a MavenPublication
build.gradle
task sourceJar(type: Jar) {
from sourceSets.main.allJava
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar {
classifier "sources"
}
}
}
}
关于如何自定义工件的更详细的文档,请参阅MavenPublication
。
See MavenPublication
for more detailed documentation on how artifacts can be customized.
生成的 POM
文件的属性中,包含了从以下项目属性中获得的标识值:
The attributes of the generated POM
file will contain identity values derived from the following project properties:
groupId
- Project.getGroup()
artifactId
- Project.getName()
version
- Project.getVersion()
重写默认标识值很简单︰只需要配置MavenPublication
时指定groupId
、artifactId
或version
的属性。
Overriding the default identity values is easy: simply specify the groupId
, artifactId
or version
attributes when configuring the MavenPublication
.
示例 65.4. 自定义发布标识 - Example 65.4. customizing the publication identity
build.gradle
publishing { publications { maven(MavenPublication) { groupId 'org.gradle.sample' artifactId 'project1-sample' version '1.1' from components.java } } }
Maven 将“groupId”和“artifactId”限制为有限的字符集([A-Za-z0-9_\\-.]+
),并且 Gradle 强制执行该限制。对于“version”(以及工件的“extension”和“classifier”),只要是有效的Unicode字符,Gradle 都会处理。
Maven restricts 'groupId' and 'artifactId' to a limited character set ([A-Za-z0-9_\\-.]+
) and Gradle enforces this restriction. For 'version' (as well as artifact 'extension' and 'classifier'), Gradle will handle any valid Unicode character.
唯一明确禁止使用的 Unicode 值是“”\
”、“/
”以及所有的 ISO 控制字符。提供的值会在发布的早期阶段进行验证。
The only Unicode values that are explicitly prohibited are '\
', '/
' and any ISO control character. Supplied values are validated early in publication.
有时候,从项目信息生成的 POM 文件需要在发布前进行调整。“maven-publish
”插件提供了一个钩子以允许这样的修改。
At times, the POM file generated from the project information will need to be tweaked before publishing. The “maven-publish
” plugin provides a hook to allow such modification.
示例 65.5. 修改 POM 文件 - Example 65.5. Modifying the POM file
build.gradle
publications { mavenCustom(MavenPublication) { pom.withXml { asNode().appendNode('description', 'A demonstration of maven POM customization') } } }
在这个例子中我们为生成的 POM 添加了一个“description”元素。通过这个钩子,你可以修改 POM 的任何方面的内容。例如,你可以把一个依赖的版本范围修改为用于生成构建的实际版本。
In this example we are adding a 'description' element for the generated POM. With this hook, you can modify any aspect of the POM. For example, you could replace the version range for a dependency with the actual version used to produce the build.
相关的 API 参考文档,请参阅MavenPom.withXml()
。
See MavenPom.withXml()
for the relevant API reference documentation.
如果需要,几乎可以修改所创建POM的任何方面的内容。这意味着,你也可能把一个 POM 修改成无效的 Maven Pom,因此在使用这一功能时必须小心。
It is possible to modify virtually any aspect of the created POM should you need to. This means that it is also possible to modify the POM in such a way that it is no longer a valid Maven Pom, so care must be taken when using this feature.
已发布模块的标识符(groupId,artifac,version)则是一个例外;这些值不能在POM中使用“withXML”钩子修改。
The identifier (groupId, artifactId, version) of the published module is an exception; these values cannot be modified in the POM using the `withXML` hook.
有时候,不需要创建单独的 Gradle 子项目就能从 Gradle 构建中发布多个模块会很有用。一个例子是为你的库发布一个单独的 API 和实现 jar。使用 Gradle 的话很简单:
Sometimes it's useful to publish multiple modules from your Gradle build, without creating a separate Gradle subproject. An example is publishing a separate API and implementation jar for your library. With Gradle this is simple:
示例 65.6. 从单项目中发布多个模块 - Example 65.6. Publishing multiple modules from a single project
build.gradle
task apiJar(type: Jar) { baseName "publishing-api" from sourceSets.main.output exclude '**/impl/**' } publishing { publications { impl(MavenPublication) { groupId 'org.gradle.sample.impl' artifactId 'project2-impl' version '2.3' from components.java } api(MavenPublication) { groupId 'org.gradle.sample' artifactId 'project2-api' version '2' artifact apiJar } } }
如果一个项目定义了多个发布,那么 Gradle 会将每个发布都发布到定义的仓库中。每个发布都必须x给定如上所述的唯一标识。
If a project defines multiple publications then Gradle will publish each of these to the defined repositories. Each publication must be given a unique identity as described above.
要发布的内容会被发布到仓库中。要发布到的仓库由 PublishingExtension.getRepositories()
容器定义。
Publications are published to repositories. The repositories to publish to are defined by the PublishingExtension.getRepositories()
container.
示例 65.7. 声明要发布到的仓库 - Example 65.7. Declaring repositories to publish to
build.gradle
repositories { maven { url "$buildDir/repo" // change to point to your repo, e.g. http://my.org/repo } }
用于声明要发布的仓库的 DSL 与用于声明查找依赖的仓库的DSL一样,都是使用 RepositoryHandler
。但是,在 Maven 发布的场景中,只有 MavenArtifactRepository
仓库才可以用于发布。
The DSL used to declare repositories for publication is the same DSL that is used to declare repositories to consume dependencies from, RepositoryHandler
. However, in the context of Maven publication only MavenArtifactRepository
repositories can be used for publication.
对每一个在 publishing.publications
和 publishing.repositories
容器中分别组合的MavenPublication
和 MavenArtifactRepository
,“maven-publish
” 插件自动为它们创建了一个 PublishToMavenRepository
任务。
The “maven-publish
” plugin automatically creates a PublishToMavenRepository
task for each MavenPublication
and MavenArtifactRepository
combination in the publishing.publications
and publishing.repositories
containers respectively.
这个创建的任务使用“publish«PUBLICATION 名称»PublicationTo«REPOSITORY 名称»Repository
”的模式来命名。
The created task is named using the pattern "publish«NAME OF PUBLICATION»PublicationTo«NAME OF REPOSITORY»Repository
".
示例 65.8. 将项目发布到 Maven 仓库 - Example 65.8. Publishing a project to a Maven repository
build.gradle
apply plugin: 'java' apply plugin: 'maven-publish' group = 'org.gradle.sample' version = '1.0' publishing { publications { mavenJava(MavenPublication) { from components.java } } repositories { maven { url "$buildDir/repo" // change to point to your repo, e.g. http://my.org/repo } } }
gradle publish
的输出结果
Output of gradle publish
> gradle publish :generatePomFileForMavenJavaPublication :compileJava :processResources UP-TO-DATE :classes :jar :publishMavenJavaPublicationToMavenRepository :publish BUILD SUCCESSFUL Total time: 1 secs
因此,在这个例子中,添加了一个 PublishToMavenRepository
任务,命名为“ publishMavenJavaPublicationToMavenRepository
”,这个任务会被连接到publish
生命周期任务中。执行 gradle publish
会构建 POM 文件和所有要发布的工件,并将它们传到仓库。
So in this example a single PublishToMavenRepository
task is be added, named 'publishMavenJavaPublicationToMavenRepository
'. This task is wired into the publish
lifecycle task. Executing gradle publish
builds the POM file and all of the artifacts to be published, and transfers them to the repository.
为了与本地 Maven 安装集成,有时将模块发布到本地 .m2 仓库中会很有用。在 Maven 用语中,这称为“安装”模块。“maven-publish
”插件通过为publishing.publications
容器中的每个MavenPublication
任务,自动创建一个PublishToMavenLocal
任务,使得它很容易实现。其中每一个任务都连接到publishToMavenLocal
生命周期任务中。你不需要在“publishing.repositories”代码段中使用“mavenLocal”。
For integration with a local Maven installation, it is sometimes useful to publish the module into the local .m2 repository. In Maven parlance, this is referred to as 'installing' the module. The “maven-publish
” plugin makes this easy to do by automatically creating a PublishToMavenLocal
task for each MavenPublication
in the publishing.publications
container. Each of these tasks is wired into the publishToMavenLocal
lifecycle task. You do not need to have `mavenLocal` in your `publishing.repositories` section.
这个创建的任务使用“publish«PUBLICATION 名称»PublicationToMavenLocal
”的模式来命名。
The created task is named using the pattern "publish«NAME OF PUBLICATION»PublicationToMavenLocal
".
示例 65.9. 发布项目到 Maven 本地仓库 - Example 65.9. Publish a project to the Maven local repository
gradle publishToMavenLocal
的输出结果
Output of gradle publishToMavenLocal
> gradle publishToMavenLocal :generatePomFileForMavenJavaPublication :compileJava :processResources UP-TO-DATE :classes :jar :publishMavenJavaPublicationToMavenLocal :publishToMavenLocal BUILD SUCCESSFUL Total time: 1 secs
因此,在这个示例中,你可以看到添加了一个名为“publishMavenJavaPublicationToMavenLocal
”的PublisheToMavenLocal
任务。这个任务连接到publishToMavenLocal
生命周期任务中。执行 gradle publishToMavenLocal
会构建 POM 文件和所有要发布的工件,并将它们“安装”到本地 Maven 仓库中。
So in this example you can see that a single PublishToMavenLocal
task is be added, named 'publishMavenJavaPublicationToMavenLocal
'. This task is wired into the publishToMavenLocal
lifecycle task. Executing gradle publishToMavenLocal
builds the POM file and all of the artifacts to be published, and 'installs' them into the local Maven repository.
有时候我们会需要在实际上不发布的情况下,为模块生成一个 Maven POM 文件。由于POM生成是由单独的任务执行的,因此这样做很简单。
At times it is useful to generate a Maven POM file for a module without actually publishing. Since POM generation is performed by a separate task, it is very easy to do so.
生成 POM 文件的任务为 GenerateMavenPom
类型,并且根据发布的名称它被命名为:“generatePomFileFor«PUBLICATION 的名称»发布
”。因此,在下面的示例中,如果发布名为“mavenCustom
”,则任务将命名为“generatePomFileForMavenCustomPublication
”。
The task for generating the POM file is of type GenerateMavenPom
, and it is given a name based on the name of the publication: "generatePomFileFor«NAME OF PUBLICATION»Publication
". So in the example below, where the publication is named "mavenCustom
", the task will be named "generatePomFileForMavenCustomPublication
".
示例 65.10. 生成POM文件而不发布 - Example 65.10. Generate a POM file without publishing
build.gradle
model {
tasks.generatePomFileForMavenCustomPublication {
destination = file("$buildDir/generated-pom.xml")
}
}
gradle generatePomFileForMavenCustomPublication
的输出结果
Output of gradle generatePomFileForMavenCustomPublication
> gradle generatePomFileForMavenCustomPublication :generatePomFileForMavenCustomPublication BUILD SUCCESSFUL Total time: 1 secs
发布模型的所有细节仍然要在 POM 生成中考虑,包括compon
,自定义artifacts
,以及通过pom.withXml
所做的任何修改。
All details of the publishing model are still considered in POM generation, including components
`, custom artifacts
, and any modifications made via pom.withXml
.
“maven-publish
”插件利用了后期插件配置的一些实验性的支持,在发布扩展配置前,不会构造 GenerateMavenPom
任务。确保在你尝试访问 GenerateM
任务时,发布插件已经配置的最简单的方法是将访问放在 publishing
块中,如上面的例子中所示。
The “maven-publish
” plugin leverages some experimental support for late plugin configuration, and any GenerateMavenPom
tasks will not be constructed until the publishing extension is configured. The simplest way to ensure that the publishing plugin is configured when you attempt to access the GenerateMavenPom
task is to place the access inside a publishing
block, as the example above demonstrates.
这同样适用于尝试访问发布内容相关的任务(如 PublishToMavenRepository
)。这些任务应该在 publishing
块中引用。
The same applies to any attempt to access publication-specific tasks like PublishToMavenRepository
. These tasks should be referenced from within a publishing
block.