前言:本文是对Gradle用户手册的试译。遵循中英文对照原则。
发布到Maven仓库
Chapter 34. Maven Publishing (new)
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.
If you are looking for documentation on the original Maven publishing support using the Upload task please see Chapter 30, Publishing artifacts.
章34: 发布到Maven仓库
本章描述了新孵化的Maven发布插件-“maven-publish”提供的支持。最终这个新支持的发布插件将替代通过上传任务(Upload task)实现的发布。
如果你在寻找通过上传任务实现的Maven发布方式的原始文档,请查看第30章: 发布构件。[](发布构件的翻译很不贴切。)
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 23, Dependency Management) and other tools that understand the Maven repository format.
本章描述怎么发布构建构件到一个Maven仓库。一个模块发布到Maven仓库可以使用Maven、Gradle(参考章23: 依赖管理)和其他理解Maven仓库格式的工具。
“maven-publish” 插件
34.1. The “maven-publish” Plugin
The ability to publish in the Maven format is provided by the “maven-publish” plugin.
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.
Example 34.1. Applying the ‘maven-publish’ plugin
build.gradle apply plugin: 'maven-publish'
Applying the “maven-publish” plugin does the following:
Applies the “publishing” plugin
Establishes a rule to automatically create a GenerateMavenPom task for each MavenPublication added (see Section 34.2, “Publications”).
Establishes a rule to automatically create a PublishToMavenRepository task for the combination of each MavenPublication added (see Section 34.2, “Publications”), with each MavenArtifactRepository added (see Section 34.3, “Repositories”).
Establishes a rule to automatically create a PublishToMavenLocal task for each MavenPublication added (seeSection 34.2, “Publications”).
34.1. “maven-publish” 插件
发布Maven格式的能力是由 “maven-publish”插件提供的。
“publishing” 插件为项目创建了一个名为 “publishing”、类型为PublishingExtension的扩展。这个扩展提供了一个名为publications的容器和一个名为repositories的容器。 “maven-publish” 插件与MavenPublication一起工作。
Example 34.1. Applying the ‘maven-publish’ plugin
build.gradle apply plugin: 'maven-publish'
完成下列步骤,应用“maven-publish”插件
应用“publishing”插件
建立一个规则,为每一个MavenPublication自动创建一个GenerateMavenPom任务参考第32章:“Publications”
建立一个规则,为每个MavenArtifactRepository的每个MavenPublication自动创建一个PublishToMavenRepository任务
建立一个规则,为每个已添加的MavenPublication自动创建一个PublishToMavenLocal任务
发布
34.2. Publications
If you are not familiar with project artifacts and configurations, you should read the Chapter 30, 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.
34.2. 发布
如果你不熟悉项目构件和配置,你应该去阅读第30章-介绍这些概念。 本章使用不同的机制描述发布构件的概念。这里描述的发布功能最终将取代那些功能。
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.
Publication objects描述了被创建publication结构和配置。Publications通过任务发布到存储库,publication object的配置精确的决定发布哪些内容。一个项目的所有publications被定义在PublishingExtension.getPublications()容器。每个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.
如要“maven-publish”插件生效,必须在publications中添加一个MavenPublication。这个publication决定发布哪些构件及Pom文件间的联系细节。一个publication可以通过添加部件、配置构件及直接修改生成的Pom文件配置。
发布一个组件
34.2.1. Publishing a Software Component
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:
Table 34.1. Software Components
Name Provided By Artifacts Dependencies
java Chapter 45, The Java Plugin Generated jar file Dependencies from 'runtime' configuration
web Chapter 47, The War Plugin Generated war file No dependencies
In the following example, artifacts and runtime dependencies are taken from the java
component, which is added by the Java Plugin.
Example 34.2. Adding a MavenPublication for a Java component
build.gradle
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
发布一个软件组件
发布一个Gradle项目到Maven仓库最简单的方式是指定一个SoftwareComponent发布。目前可发布的组件有:
表 34.1. 软件组件
名字 提供者 构件 依赖
java Chapter 45, The Java Plugin 生成jar文件 Dependencies from 'runtime' configuration
web Chapter 47, The War Plugin 生成war文件 No dependencies
在接下来的示例中,构件和运行时依赖来自java插件添加的java组件。
示例34.2 为一个java组件添加MavenPublication
build.gradle
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
发布定制构件
34.2.2. Publishing custom artifacts
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).
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:
也可以显式的配置publication包含的构件。构件通常提供原始文件或者AbstractArchiveTask(例如:jar、zip)实例。
对于所有定制构件,也可以指定用于publication的extension(分类)。注意,只有一个发布构件可以拥有空的classifer,其他所有构件必须拥有一个唯一的classfier/extension组合。
配置定制构件如下:
Example 34.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类的Api文档查看更多定制构件的信息。
生成Pom文件中的标识值
34.2.3. Identity values in the generated 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()
Overriding the default identity values is easy: simply specify the groupId, artifactId or version attributes when configuring the MavenPublication.
自动生成的Pom文件的属性包含的标识值来自以下Project属性:
组织id –Project.getGroup()
构件id –Project.getName()
可以轻易重写默认标识值:仅需在配置MavenPublication时指定groupId, artifactId 或者 version 属性。
Example 34.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 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.
Maven用一个有限字符集([A-Za-z0-9_\\-.]+)约束’groupId’和’artifactId’,Gradle执行这一约束。对于’version’(’extension’和’classifier’),Gradle能处理任何有效的Unicode字符。
The only Unicode values that are explicitly prohibited are ‘\’, ‘/’ and any ISO control character. Supplied values are validated early in publication.
被明确禁止使用的Unicode字符是’\’,’/’和其他ISO控制字符。这里提供的值已在早期publication验证。
Certain repositories will not be able to handle all supported characters. For example, the ‘:’ character cannot be used as an identifier when publishing to a filesystem-backed repository on Windows.
某些存储库可能不支持所有的字符。比如,’:’字符在发布到Windows系统文件存储库时不能用作标识值。
编辑POM
Modifying the generated POM
The generated POM file may need to be tweaked before publishing. The “maven-publish” plugin provides a hook to allow such modification.
生成的Pom文件在发布前可能需要调整。’maven-publish’插件提供了钩子允许做一些编辑。
Example 34.5. Modifying the POM file
build.gradle
publications {
mavenCustom(MavenPublication) {
pom.withXml {
asNode().appendNode('description',
'A demonstration of maven POM customization')
}
}
}
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.
在这个例子中,我们为生成的Pom文件添加了一个’description’节点。通过这个钩子,你可以修改Pom的任何方面。例如,你可以替换依赖的版本范围为生产环境中实际使用的版本。
See MavenPom.withXml() in the API documentation for more information.
查看Api中的MavenPom.withXml())获得更多详细信息。
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.
可以根据需要修改创建Pom的几乎任何方面。这意味着可能修改的Pom不再是一个有效的Maven Pom,所以必须小心使用这个特性。
The identifier (groupId, artifactId, version) of the published module is an exception; these values cannot be modified in the POM using the withXML
hook.
发布模块的标识(groupId, artifactId, version)是一个例外;他们的值不能通过withXML
钩子修改。
发布多模块
34.2.5. Publishing multiple modules
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:
在不创建一个单独的子项目时,通过Gradle build发布成多模块有时是有用的。一个例子在库发布了一个Api模块和实现模块。使用Gradle可以简单实现:
Example 34.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
}
}
}
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.
如果一个项目定义了多个publications,Gradle将发布他们到定义的仓库中。如上描述,每个publication都要拥有一个唯一的标识。
存储库
34.3. Repositories
Publications are published to repositories. The repositories to publish to are defined by the PublishingExtension.getRepositories() container.
Publications发布到存储库。发布的存储库由 PublishingExtension.getRepositories()定义。
Example 34.7. Declaring repositories to publish to
build.gradle
publishing {
repositories {
maven {
// change to point to your repo, e.g. http://my.org/repo
url "$buildDir/repo"
}
}
}
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.
定义发布存储库的DSL与定义依赖存储库的DSL相同,是RepositoryHandler。但是,在Maven publication上下文中只有MavenArtifactRepository存储库可以用来发布构件。
执行发布
34.4. Performing a publish
The “maven-publish” plugin automatically creates a PublishToMavenRepository task for each MavenPublication and MavenArtifactRepository combination in the publishing.publications and publishing.repositories containers respectively.
“maven-publish”插件自动为每个MavenPublication和MavenArtifactRepository组合创建一个PublishToMavenRepository任务。publications和publishing.repositories分别是各自的容器。
The created task is named “publish«PUBNAME»PublicationTo«REPONAME»Repository”.
这个被创建的任务称为:“publish«PUBNAME»PublicationTo«REPONAME»Repository”。
Example 34.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
}
}
}
publishing {
repositories {
maven {
// change to point to your repo, e.g. http://my.org/repo
url "$buildDir/repo"
}
}
}
Output of gradle publish
> gradle publish
:generatePomFileForMavenJavaPublication
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:publishMavenJavaPublicationToMavenRepository
:publish
BUILD SUCCESSFUL
Total time: 1 secs
In this example, a task named “publishMavenJavaPublicationToMavenRepository” is created, which is of type PublishToMavenRepository. 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.
在这个示例中,一个名为“publishMavenJavaPublicationToMavenRepository”的任务被创建,它是PublishToMavenRepository类型的。这个任务被写入到发布任务的生命周期中。执行“gradle publish”构建Pom文件和所有发布构件并转移它们到存储库中。
发布到Maven本地仓库
34.5. Publishing to Maven Local
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.
为了集成安装的本地Maven,有时会发布模块到本地.m2存储库中。在Maven语法中,这被称为安装模块。“maven-publish”为每个publishing.publications自动创建了一个PublishToMavenLocal任务。所有相关任务都会被写入到publishToMavenLocal任务的生命周期中。你不必在publishing.repositories
添加mavenLocal
。
The created task is named “publish«PUBNAME»PublicationToMavenLocal”.
这个被创建的任务被称为“publish«PUBNAME»PublicationToMavenLocal”。
Example 34.9. Publish a project to the Maven local repository
Output of gradle publishToMavenLocal
> gradle publishToMavenLocal
:generatePomFileForMavenJavaPublication
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:publishMavenJavaPublicationToMavenLocal
:publishToMavenLocal
BUILD SUCCESSFUL
Total time: 1 secs
The resulting task in this example is 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.
由此产生的任务在这个例子中被命名为“publishMavenJavaPublicationToMavenLocal”。这个任务被写入到publishToMavenLocal任务的生命周期中。执行“gradle publishToMavenLocal”构建Pom文件和所有构件并‘安装’到本地Maven存储库中。
不发布生成Pom文件
34.6. Generating the POM file without publishing
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.
生成Maven Pom文件而不实际发布构件有时是有用的。因为生成Pom是由一个单独任务执行的,所以是非常容易做到这一点的。
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«PUBNAME»Publication”. So in the example below, where the publication is named “mavenCustom”, the task will be named “generatePomFileForMavenCustomPublication”.
生成Pom文件的任务是GenerateMavenPom类型,它被赋予一个名字:“generatePomFileFor«PUBNAME»Publication”。所以在下面的例子中,如果publication名为“mavenCustom”,这个任务名将是“generatePomFileForMavenCustomPublication”。
Example 34.10. Generate a POM file without publishing
build.gradle
model {
tasks.generatePomFileForMavenCustomPublication {
destination = file("$buildDir/generated-pom.xml")
}
}
Output of gradle generatePomFileForMavenCustomPublication
> gradle generatePomFileForMavenCustomPublication
:generatePomFileForMavenCustomPublication
BUILD SUCCESSFUL
Total time: 1 secs
All details of the publishing model are still considered in POM generation, including components`, custom artifacts, and any modifications made via pom.withXml.
发布模块的细节还在优化考虑中,包括生成Pom文件、包含部件、定制构件和任何通过pom.withXml的修改。
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 model block, as the example above demonstrates.
The same applies to any attempt to access publication-specific tasks like PublishToMavenRepository. These tasks should be referenced from within a model block.