Глава 36. Публикация Maven (новая).

Эта глава описывает поддержку новой инкубационной публикации Maven, предоставляемой плагином 'maven-publish'. В конечном счете, поддержка новой публикации заменит публикацию посредством задачи Upload.

Примечание: Подпись сгенерированного плагином файла POM на данный момент не поддерживается. В будущих версиях Gradle такая функциональность может быть добавлена. Пожалуйста, используйте плагин Maven для публикации ваших артефактов в Maven Central.

Если вы ищите документацию об исходной публикации Maven с использованием задачи Upload, пожалуйста, смотрите Главу 32 Публикация артефактов.

В этой главе рассказывается о том как публиковать собранные артефакты в хранилище Apache Maven. Модуль, опубликованный в хранилище Maven, может быть использован Maven, Gradle (смотрите Главу 25 Управление зависимостями) и другими инструментами, которые понимают формат хранилища Maven.

36.1. Плагин 'maven-publish'.

Возможность публиковать в формате Maven предоставляется плагином 'maven-publish'.

Плагин 'publishing' создает расширение проекта с именем 'publishing' типа PublishingExtension. Это расширение предоставляет контейнер именованных публикаций и контейнер именованных хранилищ. Плагин 'maven-publish' работает с публикациями MavenPublication и хранилищами MavenArtifactRepository.

Пример 36.1. Применение плагина 'maven-publish'

build.gradle

apply plugin: 'maven-publish'
	  

Применение плагина 'maven-publish' делает следующее:

  • Применяет плагин 'publishing'.
  • Устанавливает правило автоматического создания задачи GenerateMavenPom для каждой добавленной MavenPublication (смотрите Секцию 36.2 Публикации).
  • Устанавливает правило автоматического создания задачи PublishToMavenRepository для комбинации каждой добавленной MavenPublication (смотрите Секцию 36.2 Публикации) с каждым добавленным MavenArtifactRepository (смотрите Секцию 36.3 Хранилища).
  • Устанавливает правило автоматического создания задачи PublishToMavenLocal для каждой добавленной MavenPublication (смотрите Секцию 36.2 Публикации).

36.2. Публикации.

Если вы не знакомы с артефактами и конфигурациями проекта, вам следует прочесть Главу 32 Публикация артефактов, которая вводит эти понятия. В той главе также описывается 'публикация артефактов' с использованием другого механизма, отличного от описываемого в этой. Функциональность публикации, описанная здесь, в конечном итоге, заменит ту.

Объекты публикации описывают структуру/конфигурацию публикации, которая будет создана. Публикации публикуются в хранилища посредством задач и настройка объектов публикации определяет то, что публикуется. Все публикации проекта определены в контейнере PublishingExtension.getPublications(). У каждой публикации уникальное имя в рамках проекта.

Для того, чтобы плагин 'maven-publish' имел какой-либо эффект, к набору публикаций должна быть добавлена MavenPublication. Эта публикация определяет какие артефакты в действительности публикуются, наряду с деталями, включенными в связанный файл POM. Публикацию можно настроить, добавив компоненты, настроив артефакты и непосредственно изменив сгенерированный файл описания модуля.

36.2.1. Публикация компонента программного обеспечения.

Простейший путь опубликовать проект Gradle в хранилище Ivy - указать SoftwareComponent для публикации. Компоненты доступные для публикации в настоящее время:

Таблица 36.1. Компоненты программного обеспечения
ИмяПредоставленАртефактыЗависимости
javaПлагином JavaСгенерированный jar-файлЗависимости из конфигурации 'runtime'
webПлагином WarСгенерированный war-файлНет зависимостей

В следующем примере, артефакты и зависимости времени выполнения взяты из компонента 'java', который добавлен плагином Java.

Пример 36.2. Добавление MavenPublication для компонента Java

build.gradle

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
}
	  

36.2.2. Публикация пользовательских артефактов.

Возможна точная настройка того, какие артефакты будут включены в публикацию. Артефакты обычно предоставляемые как сырые файлы или экземпляры AbstractArchiveTask (например, Jar, Zip).

Для каждого пользовательского артефакта возможно указать значения свойств extension и classifier, используемых публикацией. Обратите внимание, что только один опубликованный артефакт может иметь пустой classifier, а все остальные должны иметь уникальную комбинацию classifier/extension.

Пользовательские артефакты настраиваются так:

Пример 36.3. Добавление дополнительного артефакта в MavenPublication

build.gradle

task sourceJar(type: Jar) {
    from sourceSets.main.allJava
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java

            artifact sourceJar {
                classifier "sources"
            }
        }
    }
}
	  

Смотрите класс MavenPublication в документации API, чтобы узнать больше о том, как можно настроить артефакты.

36.2.3. Идентификационные данные в сгенерированном файле POM.

Атрибуты сгенерированного файла POM будут содержать идентификационным данные полученные из следующих свойств проекта:

Переопределить значения по умолчанию идентификационных данных легко: просто укажите атрибуты groupId, artifactId или version при настройке MavenPublication.

Пример 36.4. Настройка идентификационных данных публикации

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') можно использовать любой подходящий символ юникода.

Определенные хранилища не в состоянии обработать все поддерживаемые символы. Например, символ ':' невозможно использовать в качестве идентификатора при публикации в хранилище, основанное на файловой системе Windows.

36.2.4. Изменение сгенерированного файла POM.

Перед публикацией может понадобиться точно настроить сгенерированный файл POM. Плагин 'maven-publish' предоставляет перехватчик, чтобы сделать возможным такие изменения.

Пример 36.5. Изменение файла POM

build.gradle

publications {
    mavenCustom(MavenPublication) {
        pom.withXml {
            asNode().appendNode('description',
                                'A demonstration of maven POM customization')
        }
    }
}
	  

В этом примере мы добавляем элемент 'description' к сгенерированному файлу POM. С этим перехватчиком вы можете изменить любой аспект файла POM. Например, вы можете заменить диапазон версий зависимости на актуальную версию, используемую создания сборки.

Чтобы узнать больше, смотрите MavenPom.withXml(org.gradle.api.Action) в документации API.

Можно изменить практически любой аспект созданного файла POM. Также это означает, что можно изменить POM таким образом, что оно больше не будет действительным Maven POM, поэтому при использовании этой функции необходимо соблюдать осторожность.

Идентификатор (groupId, artifactId, version) опубликованного модуля является исключением; эти значения невозможно изменить в POM-файле с помощью перехватчика 'withXML'.

36.2.5. Публикация нескольких модулей.

Иногда бывает полезно опубликовать несколько модулей из вашей сборки Gradle, без создания отдельного подпроекта. Например, публикация отдельного API и jar-файла с реализацией для вашей библиотеки. С Gradle это просто:

Пример 36.6. Публикация нескольких модулей из одного проекта

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 опубликует каждую из них в заданное хранилище. Каждая публикация должна уникально идентифицироваться, как было описано выше.

36.3. Хранилища.

Публикации публикуются в хранилища. Хранилища для публикации определяются контейнером PublishingExtension.getRepositories().

Пример 36.7. Объявление хранилищ для публикации

build.gradle

publishing {
    repositories {
        maven {
            // change to point to your repo, e.g. http://my.org/repo
            url "$buildDir/repo"
        }
    }
}
	  

DSL используемый для объявления хранилищ для публикации такой же как используемый для объявления хранилищ, откуда берутся зависимости, RepositoryHandler. Однаком, в контексте публикации Maven, только хранилища MavenArtifactRepository можно использовать для публикации.

36.4. Выполнение публикации.

Плагин 'maven-publish' автоматически создает задачу PublishToMavenRepository для каждой комбинации MavenPublication и MavenArtifactRepository в контейнерах publishing.publications и publishing.repositories соответственно.

Созданная задача называется 'publish«ИМЯ_ПУБЛИКАЦИИ»PublicationTo«ИМЯ_ХРАНИЛИЩА»Repository'.

Пример 36.8. Публикация проекта в хранилище Maven

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"
        }
    }
}
	  

Вывод команды gradle publish

> gradle publish
:generatePomFileForMavenJavaPublication
:compileJava
:processResources NO-SOURCE
:classes
:jar
:publishMavenJavaPublicationToMavenRepository
:publish

BUILD SUCCESSFUL

Total time: 1 secs
	  

36.5. Публикация в локальное хранилище Maven.

Для итеграции с локальной установкой Maven, иногда бывает полезно опубликовать модуль в локальное хранилище .m2. Говоря языком Maven, это означает 'установить' модуль. Плагин 'maven-publish' облегчает этот процесс, создавая задачу PublishToMavenLocal для каждой MavenPublication в контейнере publishing.publications. Каждая из этих задач связана с задачей жизненного цикла publishToMavenLocal. Нет необходимости иметь 'mavenLocal' в вашей секции 'publishing.repositories'.

Созданная задача называется 'publish«ИМЯ_ПУБЛИКАЦИИ»PublicationToMavenLocal'.

Пример 36.9. Публикация проекта в локальное хранилище Maven

Вывод команды gradle publishToMavenLocal

> gradle publishToMavenLocal
:generatePomFileForMavenJavaPublication
:compileJava
:processResources NO-SOURCE
:classes
:jar
:publishMavenJavaPublicationToMavenLocal
:publishToMavenLocal

BUILD SUCCESSFUL

Total time: 1 secs
	  

Результирующая задача в этом примере - 'publishMavenJavaPublicationToMavenLocal'. Эта задача связана с задачей жизненнго цикла 'publishToMavenLocal'. Выполнение 'gradle publishToMavenLocal' соберет файл POM и все артефакты для публикации и 'установит' их в локальное хранилище Maven.

36.6. Генерация файла POM без публикации.

Временами бывает полезно сгенерировать файл Maven POM для модуля без его публикации. Так как генерация такого файла выполняется отдельной задачей, это легко сделать.

Тип задачи для генерации файла POM - GenerateMavenPom и ее имя основано на имени публикации: 'generatePomFileFor«ИМЯ_ПУБЛИКАЦИИ»Publication'. Так, в примере ниже, где публикация называется 'mavenCustom', имя задачи будет 'generatePomFileForMavenCustomPublication'.

Пример 36.10. Генерация файла POM без публикации

build.gradle

model {
    tasks.generatePomFileForMavenCustomPublication {
        destination = file("$buildDir/generated-pom.xml")
    }
}
	  

Вывод команды gradle generatePomFileForMavenCustomPublication

> gradle generatePomFileForMavenCustomPublication
:generatePomFileForMavenCustomPublication

BUILD SUCCESSFUL

Total time: 1 secs
	  

Все детали модели публикации учитываются при генерации POM, включая components, пользовательские artifacts и любые изменения, сделанные посредством pom.withXml.

Плагин 'maven-publish' использует экспериментальную поддержку поздней настройки плагина и любая задача GenerateMavenPom не будет создана до тех пор, пока не будет настроено расширение публикации. Самым простым способом убедиться, что плагин публикации настроен, когда вы пытаетесь обратиться к задаче GenerateMavenPom, является помещение обращения в блок model, как показано в примере выше.

То же самое относится к любой попытке обращения к задачам публикации, таким как PublishToMavenRepository. Ссылаться на такие задачи надо внутри блока model.