Глава 34. Плагин подписи.

Плагин подписи добавляет возможность подписывать собранные файлы и артефакты цифровой подписью. Цифровые подписи затем можно использовать для удостоверения в том, кто собрал артефакты. Подпись прикрепляется также как другая информация (например, дата генерации подписи).

Плагин подписи на данный момент предоставляет поддержку только для генерации OpenPGP подписей (формат подписи, который требуется для публикации в центральное хранилище Maven).

34.1. Использование.

Чтобы использовать плагин подписи, включите следующее в ваш сборочный скрипт:

Пример 34.1. Использование плагина подписи

build.gradle

apply plugin: 'signing'
	  

34.2. Регистрационные данные подписавшего.

Для только, чтобы создавать OpenPGP подписи, вы потребуется пара ключей (инструкции о том как создать пару ключей с использованием инструменты GnuPG можно найти по ссылке GnuPG HOWTOs). Вам понадобится предоставить плагину подписи вашу информацию о ключах, а именно:

  • Открытый индентификатор ключа (8 символов в шестнадцатеричной строке).
  • Абсолютный путь к файлы секретных ключей, содержащему ваш закрытый ключ.
  • Пароль, защищающий закрытый ключ.

Идентификатор ключа, путь к файлы и пароль должны быть предоставлены в виде значений свойств signing.keyId, signing.secretKeyRingFile и signing.password соответственно. Учитывая их личную и секретную природу, рекомендуется хранить их в пользовательском файле gradle.properties (как это сделать, описано в Секции 12.2 Свойства Gradle и системные свойства).

signing.keyId=24875D73
signing.password=secret
signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg
          

Если указание этой инфморации (в особенности signing.password) в пользовательском файле gradle.properties невозможно для вашей среды, вы можете получать информацию когда бы вам ни понадобилось и устанавливать свойства проекта вручную.

import org.gradle.plugins.signing.Sign

gradle.taskGraph.whenReady { taskGraph ->
    if (taskGraph.allTasks.any { it instanceof Sign }) {
        // Use Java 6's console to read from the console (no good for
        // a CI environment)
        Console console = System.console()
        console.printf "\n\nWe have to sign some things in this build." +
                       "\n\nPlease enter your signing details.\n\n"

        def id = console.readLine("PGP Key Id: ")
        def file = console.readLine("PGP Secret Key Ring File (absolute path): ")
        def password = console.readPassword("PGP Private Key Password: ")

        allprojects { ext."signing.keyId" = id }
        allprojects { ext."signing.secretKeyRingFile" = file }
        allprojects { ext."signing.password" = password }

        console.printf "\nThanks.\n\n"
    }
}
          

34.2.1. Использование подключей OpenPGP.

OpenPGP поддерживает подключи, которые похожи на обычные ключи, за тем исключением, что они привязаны к основной паре ключей. Одна из возможностей подключей OpenPGP заключается в том, что они могут быть аннулированы независимо от основных ключей, что делает управление ключами легче. О практической пользе подключей в разработке программного обеспечения можно прочитать на Debian wiki.

Плагин подписи поддерживает подключи OpenPGP 'из коробки'. Просто укажите идентификатор подключа в качестве значения свойства signing.keyId.

34.3. Указание того, что надо подписать.

Наряду с настройкой процесса подписи (конфигурации подписывающего), вы должны также указать что подписать. Плагин подписи предоставляет DSL, который позволяет вам указать задачи и/или конфигурации, которые должны быть подписаны.

34.3.1. Подпись конфигураций.

Обычно хотят подписывать артефакты конфигурации. Например, плагин Java настраивается для сборки jar-файла и jar-артефакт добавляется к конфигурации archives. Используя DSL подписи, вы можете указать, что все артефакты этой конфигурации должны быть подписаны.

Пример 34.2. Подпись конфигурации

build.gradle

signing {
    sign configurations.archives
}
	  

Этот код создаст задачу (типа Sign) в вашем проекте с именем 'signArchives', которая соберет любые артефакты archives (если необходимо) и затем сгенерирует подписи для них. Файлы подписей будут помещены рядом с подписанными артефактами.

Пример 34.3. Подпись выданных конфигурацией данных

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

> gradle signArchives
:compileJava
:processResources
:classes
:jar
:signArchives

BUILD SUCCESSFUL

Total time: 1 secs
	  

34.3.2. Подпись задач.

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

Пример 34.4. Подпись задачи

build.gradle

task stuffZip (type: Zip) {
    baseName = "stuff"
    from "src/stuff"
}

signing {
    sign stuffZip
}
	  

Этот код создаст задачу (типа Sign) в вашем проекте с именем 'signStuffZip', которая соберет входной архив задачи (если необходимо) и затем подпишет его. Файл подписи будет размещен вместе с подписанным артефактом.

Пример 34.5. Подпись выходных данных задачи

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

> gradle signStuffZip
:stuffZip
:signStuffZip

BUILD SUCCESSFUL

Total time: 1 secs
	  

Для того, чтобы задача была 'подписываемой', она должна выдавать архив некоторого типа. Задачи, которые выдают такие архивы - Tar, Zip, Jar, War и Ear.

34.3.3. Условная подпись.

Распространенный шаблон использования - подпись артефактов только при определенных условиях. Например, вы можете не желать подписывать артефакты в версиях, отличных от release. Чтобы достичь этого, вы можете указать, что подись требуется только при определенных условиях.

Пример 34.6. Условная подпись

build.gradle

version = '1.0-SNAPSHOT'
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")

signing {
    required { isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives") }
    sign configurations.archives
}
	  

В этом примере, вы хотим подписывать только, если собираем версию release и собирается опубликовать ее. Вследствие того, что мы проверяем граф задач для вычисления, собираемся ли публиковать или нет, мы должны установить свойству signing.required замыкание, чтобы отложить вычисление. Чтобы узнать больше, смотрите SigningExtension.setRequired(java.lang.Object).

34.4. Публикация подписей.

Когда мы указываем что подписать посредством DSL подписи, результирующие артефакты подписи автоматически добавляются к конфигурациям зависимостей signatures и archives. Это означает, что если вы хотите выгрузить ваши подписи в хранилище дистрибутивов вместе с артефактами, просто выполните задачу uploadArchives как обычно.

34.5. Подпись файлов POM.

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

Когда размещаете подписи ваших артефактов в хранилище Maven, вы также можете захотеть подписать опубликованный файл POM. Плагин подписи добавляет метод signing.signPom() (смотрите SigningExtension.signPom(org.gradle.api.artifacts.maven.MavenDeployment, groovy.lang.Closure)), который можно использовать в блоке beforeDeployment() в конфигурации задачи выгрузки.

Пример 34.7. Подпись файла POM для размещения

build.gradle

uploadArchives {
    repositories {
        mavenDeployer {
            beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
        }
    }
}
	  

Когда подпись не требуется и файл POM не может быть подписан из-за недостаточной конфигурации (т.е. нет регистрационных данных для подписи), тогда метод signPom() молча ничего не сделает.