第五十一章. 发布工件

Chapter 51. Publishing artifacts

本章介绍的是在 Gradle 1.0 版本中的原始发布机制:在 Gradle 1.3,我们引入了新的发布机制。这种新机制现在还在试验性阶段而尚未完成,它它引入了一些新的概念和特性,使得 Gradle 的发布功能更强大。
This chapter describes the original publishing mechanism available in Gradle 1.0: in Gradle 1.3 a new mechanism for publishing was introduced. While this new mechanism is incubating and not yet complete, it introduces some new concepts and features that do (and will) make Gradle publishing even more powerful.

你可以阅读第 64 章《,Ivy 发布(新)第 65 章,《Maven 发布(新)中新发布插件的内容。请尝试它们,并向我们反馈。
You can read about the new publishing plugins in Chapter 64, Ivy Publishing (new) and Chapter 65, Maven Publishing (new). Please try them out and give us feedback.

51.1. 导言

51.1. Introduction

本章介绍了如何声明项目的输出工件,以及如何使用这些工件(比如上传这些工件)。我们将项目的工件定义为项目向外界提供的文件。它可能是一个库,一个 ZIP 分发包,或任何其他文件。一个项目想发布多少个工件都可以。
This chapter is about how you declare the outgoing artifacts of your project, and how to work with them (e.g. upload them). We define the artifacts of the projects as the files the project provides to the outside world. This might be a library or a ZIP distribution or any other file. A project can publish as many artifacts as it wants.

51.2. 构件和配置

51.2. Artifacts and configurations

与依赖一样,工件也按配置进行分组。事实上,一个配置可以同时包含工件和依赖。
Like dependencies, artifacts are grouped by configurations. In fact, a configuration can contain both artifacts and dependencies at the same time.

对于项目中的每个配置,Gradle 提供了 uploadConfigurationNamebuildConfigurationName 任务。[18] 执行这些任务会构建或上传属于各自配置的工件。
For each configuration in your project, Gradle provides the tasks uploadConfigurationName and buildConfigurationName. [18] Execution of these tasks will build or upload the artifacts belonging to the respective configuration.

表格 表 23.5,“Java 插件——依赖配置”显示了 Java 插件添加的配置,其中两个配置和工件的使用有关。archives 配置是指定你的工件的标准配置。Java 插件会自动把默认 jar 指定到这个配置。我们将在第 51.5 节,《项目库详谈》中详细讨论 runtime 配置。 与依赖一样,你可以声明许多自定义配置,并将工件分配给它们。
Table Table 23.5, “Java plugin - dependency configurations” shows the configurations added by the Java plugin. Two of the configurations are relevant for the usage with artifacts. The archives configuration is the standard configuration to assign your artifacts to. The Java plugin automatically assigns the default jar to this configuration. We will talk more about the runtime configuration in Section 51.5, “More about project libraries”. As with dependencies, you can declare as many custom configurations as you like and assign artifacts to them.

51.3. 声明工件

51.3. Declaring artifacts

51.3.1. 归档任务工件

51.3.1. Archive task artifacts

你可以使用归档任务来定义工件:
You can use an archive task to define an artifact:

示例 51.1. 使用归档任务定义一个工件 - Example 51.1. Defining an artifact using an archive task

build.gradle

task myJar(type: Jar)

artifacts {
    archives myJar
}

请务必注意,你所创建的作为构建一部分的自定义归档不会自动分配给任何配置,必须进行显式的指定。
It is important to note that the custom archives you are creating as part of your build are not automatically assigned to any configuration. You have to explicitly do this assignment.

51.3.2. 文件工件

51.3.2. File artifacts

你也可以使用文件来定义工件:
You can also use a file to define an artifact:

示例 51.2. 使用文件定义工件 - Example 51.2. Defining an artifact using a file

build.gradle

def someFile = file('build/somefile.txt')

artifacts {
    archives someFile
}

Gradle 将基于文件的名字确定工件的属性。你可以自定义这些属性:
Gradle will figure out the properties of the artifact based on the name of the file. You can customize these properties:

示例 51.3. 自定义工件 - Example 51.3. Customizing an artifact

build.gradle

task myTask(type:  MyTaskType) {
    destFile = file('build/somefile.txt')
}

artifacts {
    archives(myTask.destFile) {
        name 'my-artifact'
        type 'text'
        builtBy myTask
    }
}

有基于映射的语法来定义使用文件的工件。这个映射必须饮食一个 file 条目,它可能还包含其他的工件属性:
There is a map-based syntax for defining an artifact using a file. The map must include a file entry that defines the file. The map may include other artifact properties:

示例 51.4. 用于使用文件定义工件的映射语法 - Example 51.4. Map syntax for defining an artifact using a file

build.gradle

task generate(type:  MyTaskType) {
    destFile = file('build/somefile.txt')
}

artifacts {
    archives file: generate.destFile, name: 'my-artifact', type: 'text', builtBy: generate
}

51.4. 发布工件

51.4. Publishing artifacts

我们说过,每个配置都有一个特定的上传任务。但是在执行上传之前,你必须配置上传任务,并定义这些工件要发布到的位置。你所定义的仓库(如第 50.6 节,《仓库》中所述)不会自动地用于上传。实际上,有些仓库仅允许下载工件。以下是有关如何对配置的上传任务进行配置的例子:
We have said that there is a specific upload task for each configuration. But before you can do an upload, you have to configure the upload task and define where to publish the artifacts to. The repositories you have defined (as described in Section 50.6, “Repositories”) are not automatically used for uploading. In fact, some of those repositories allow only for artifact downloading. Here is an example how you can configure the upload task of a configuration:

示例 51.5. 上传任务的配置 - Example 51.5. Configuration of the upload task

build.gradle

repositories {
    flatDir {
        name "fileRepo"
        dirs "repo"
    }
}

uploadArchives {
    repositories {
        add project.repositories.fileRepo
        ivy {
            credentials {
                username "username"
                password "pw"
            }
            url "http://repo.mycompany.com"
        }
    }
}

正如你所见,你可以使用一个现有仓库的引用,也可以创建一个新仓库。如第 50.6.8 节,《更多关于 Ivy 解析器的信息》中所述,你可以使用适合于上传的所有 Ivy 解析器。
As you can see, you can either use a reference to an existing repository or create a new repository. As described in Section 50.6.9, “More about Ivy resolvers”, you can use all the Ivy resolvers suitable for the purpose of uploading.

如果一个上传仓库定义了多个模式,Gradle 必须选择用于上传每个文件的模式。默认情况下,Gradle 会上传到由 url 及可选的 layout 参数一起定义的模式。如果没有提供 url 参数,Gradle 将使用第一个定义的 artifactPattern 进行上传;或者对于上传 Ivy 文件,将使用第一个定义的ivyPattern(如果有设置)。
If an upload repository is defined with multiple patterns, Gradle must choose a pattern to use for uploading each file. By default, Gradle will upload to the pattern defined by the url parameter, combined with the optional layout parameter. If no url parameter is supplied, then Gradle will use the first defined artifactPattern for uploading, or the first defined ivyPattern for uploading Ivy files, if this is set.

关于上传到 Maven 仓库的内容,在么 52.6 节,《与 Maven 仓库的交互》中有描述。
Uploading to a Maven repository is described in Section 52.6, “Interacting with Maven repositories”.

51.5. 关于项目库的更多信息

51.5. More about project libraries

如果你的项目是作为一个库使用,那么你需要定义这个库的工件以及这些工件的依赖。Java 插件为此添加了一个 runtime 配置,并隐式地假定 runtime 依赖是你要发布的工件的依赖。当然,这是可以完全自定义的。你可以添加自己的自定义配置,或者让现有的配置从其他配置中扩展。你可以有不同组的工件,并且这些工件有不同的依赖。这一机制非常强大和灵活。
If your project is supposed to be used as a library, you need to define what are the artifacts of this library and what are the dependencies of these artifacts. The Java plugin adds a runtime configuration for this purpose, with the implicit assumption that the runtime dependencies are the dependencies of the artifact you want to publish. Of course this is fully customizable. You can add your own custom configuration or let the existing configurations extend from other configurations. You might have different group of artifacts which have a different set of dependencies. This mechanism is very powerful and flexible.

如果有人希望把你的项目作为一个库使用,那么她只需要在要依赖的依赖配置上声明。Gradle 依赖提供了 configuration 属性来声明它。如果这个属性没有指定,则使用 default 配置(见 第 50.4.9 节,《依赖配置》)。把一个项目作为库使用,可能是因为多项目构建,也可能是从仓库中获取项目。在后一种情况下,仓库中的 ivy.xml 描述符应该包含所有必要的信息。如果你使用 Maven 仓库,则没有如上所述的灵活性。有关如何发布到 Maven 仓库,请参阅第 52.6 节,《与 Maven 存储库交互》一节。
If someone wants to use your project as a library, she simply needs to declare on which configuration of the dependency to depend on. A Gradle dependency offers the configuration property to declare this. If this is not specified, the default configuration is used (see Section 50.4.9, “Dependency configurations”). Using your project as a library can either happen from within a multi-project build or by retrieving your project from a repository. In the latter case, an ivy.xml descriptor in the repository is supposed to contain all the necessary information. If you work with Maven repositories you don't have the flexibility as described above. For how to publish to a Maven repository, see the section Section 52.6, “Interacting with Maven repositories”.



[18] 确切地说,Base 插件提供了这些任务。这个插件会在你使用 Java 插件时自动地应用进来。
[18] To be exact, the Base plugin provides those tasks. This plugin is automatically applied if you use the Java plugin.