Избегайте запроса подписи gpg при использовании плагина релиза Maven
У меня есть проект Maven, который я пытаюсь настроить для использования плагина релиза maven. Часть процесса выпуска заключается в использовании подключаемого модуля Maven GPG для подписи артефактов, что, помимо прочего, требует успеха ключевой фразы ключа подписи GPG. Поскольку эти сборки должны выполняться в неинтерактивной среде (CI-Server), эти параметры передаются в качестве аргументов maven в форме
-Dgpg.passphrase=XXX
Для сборок снимков все работает нормально; Плагин Maven GPG видит переданную парольную фразу, артефакты создаются, подписываются и развертываются, как и ожидалось, однако, когда я пытаюсь использовать плагин релиза, мне предлагается ввести пароль ключа подписи gpg. Я прочитал несколько дискуссий по схожим вопросам, которые возникают из-за того, что плагин релиза порождает еще один вызов maven, который не получает переданные в параметрах. Наиболее популярное исправление, по-видимому, заключается в использовании параметра "arguments" следующим образом:
-Darguments="-Dgpg.passphrase=XXX"
Предположительно, это передается разветвленному экземпляру, но, к сожалению, для меня это не избавление от приглашения.
Поскольку подписание артефактов не является необычной предпосылкой для развертывания релиз-артефактов в общедоступных репозиториях Maven, и, по-видимому, большинство объектов, производящих эти артефакты, используют некую форму CI, я не могу себе представить, что я единственный человек, который столкнулся с этой проблемой. Кто-нибудь нашел обходной путь?
ПРИМЕЧАНИЕ О ПРИНЯТОМ ОТВЕТЕ:
Принятое решение не будет работать с Maven 3.0 - 3.0.3 и 3.0.3, именно так и происходит по умолчанию с java на OSX Mountain Lion. Смотрите здесь для деталей. Вам нужно будет обновить до 3.0.4.
7 ответов
Просто установите его в профиле в файле settings.xml и активируйте по умолчанию:
<settings>
<profiles>
<profile>
<id>gpg</id>
<properties>
<gpg.executable>gpg2</gpg.executable>
<gpg.passphrase>mypassphrase</gpg.passphrase>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>gpg</activeProfile>
</activeProfiles>
</settings>
Как вы можете видеть, вы можете сделать это с любым свойством, например, с другими именами пользователей и паролями для плагина jarsigner и так далее.
Это должно быть всегда активно. Это может зависеть от использования более новой версии Maven, но вы всегда можете отладить это с
mvn help:active-profiles
Шифрование пароля
Комментарии и другие ответы указывают на то, что хранение паролей в файле небезопасно... Это в некоторой степени верно, но, к счастью, Maven позволяет нам сделать это очень безопасно, создав один мастер-пароль и затем зашифровав все пароли в настройках..xml с этим.
Посмотрите мини-руководство по шифрованию паролей для деталей.
Наличие вашей парольной фразы GPG в файле в вашем домашнем каталоге абсолютно ужасно.
Вместо этого используйте gpg-agent, так что вам нужно вводить парольную фразу только один раз за сеанс. После установки вы можете настроить свою оболочку на что-то вроде:
eval $(gpg-agent --daemon --no-grab --write-env-file $HOME/.gpg-agent-info)
export GPG_TTY=$(tty)
export GPG_AGENT_INFO
затем обновите ваш плагин, чтобы включить агент. Вы можете сделать это либо в pom, либо в профиле в settings.xml, может быть лучше:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<configuration>
<useAgent>true</useAgent>
</configuration>
</plugin>
или это, вероятно, лучше и более переносимо сделать это в ваших настройках:
<profile>
<id>gpg-profile</id>
<properties>
<gpg.useagent>true</gpg.useagent>
</properties>
</profile>
Затем в первый раз в сеансе, когда требуется пароль gpg, появляется диалоговое окно. Каждый раз после этого он использует пароль от агента.
Если вы не хотите, чтобы пароль был в открытом виде в вашем файле settings.xml, и вы не хотите / не можете использовать gpg-agent, вы можете настроить шифрование пароля.
Сначала вам нужно установить мастер-пароль для maven (при условии, что maven 3.2.1+ в противном случае вы должны передать пароль в качестве аргумента):
mvn -emp
Это вернет зашифрованную версию пароля. Сохранить этот пароль в ~/.m2/settings-security.xml
- это должно выглядеть так:
<settingsSecurity>
<master>{inY3jdvspkeO2RUTxzQ4xHPelos+9EF1iFQyJQ=}</master>
</settingsSecurity>
Затем зашифруйте пароль ключа с помощью:
mvn -ep
И использовать сгенерированный зашифрованный пароль в settings.xml
(идентификатор профиля должен соответствовать используемому вами профилю, здесь я использовал release
так что вам нужно будет запустить Maven как mvn -P release release:prepare etc.
- в качестве альтернативы вы можете сделать его частью активных профилей, как подробно описано в другом ответе):
<servers>
<server>
<id>gpg.passphrase</id>
<passphrase>{inY3jdvspkeO2RUTxzQ4xHPelos}</passphrase>
</server>
</servers>
<profiles>
<profile>
<id>release</id>
<properties>
<gpg.keyname>6DF60995</gpg.keyname>
</properties>
</profile>
</profiles>
Объединив ответы здесь и официальную документацию плагина , мне удалось заставить его работать с зашифрованной парольной фразой (задокументированной здесь) в settings.xml.
settings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>YOUR_KEY_ID</id>
<passphrase>YOUR_KEY_ENCRYPTED_PASSPHRASE</passphrase>
</server>
</servers>
<profiles>
<profile>
<id>my-release</id>
<activation>
<!-- I run explicitly with "-Pmy-release". Change this to "true" if you don't want to. -->
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<gpg.keyname>YOUR_KEY_ID</gpg.keyname>
</properties>
</profile>
</profiles>
</settings>
Раздел maven-gpg-plugin в pom.xml:
<!-- Sign with GPG (properties are in ~/.m2/settings.xml) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<useAgent>true</useAgent>
<keyname>${gpg.keyname}</keyname>
<passphraseServerId>${gpg.keyname}</passphraseServerId>
<gpgArguments>
<arg>--batch</arg>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
Версия Maven: 3.6.3
Принятый ответ у меня не сработал (с использованием Maven 3.6.2). У меня сработало обновление конфигурации maven-gpg-plugin:
<plugin>
<artifactId>maven-gpg-plugin</artifactId>
....
<configuration>
<useAgent>true</useAgent>
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
<gpgArguments>
<arg>--batch</arg>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
....
</plugin>
Пароль GPG в settings.xml является рабочим решением, но он открыт, и это плохо. Альтернативное решение, которое я использовал в своих проектах, заключается в следующем:
stty -echo && printf "GPG password: " && read gpgPwd && printf '\n' && stty echo
mvn release:prepare -Darguments="-Dgpg.passphrase=$gpgPwd"
git push
git push --tags
mvn release:perform -Darguments="-Dgpg.passphrase=$gpgPwd"
unset gpgPwd
Дополнительные необходимые конфигурации:
export GPG_TTY=$(tty) (in the ~/.bash_profile)
maven-release-plugin/configuration/pushChanges=false (in the root pom.xml)
Конфигурация для много времени сложна и зависит от встроенных функций операционной системы.
Вместо того, чтобы бороться вопреки всему, мы можем использовать другой плагин, который разработан для использования в среде CI / CD.
Вы можете попробовать https://www.simplify4u.org/sign-maven-plugin/, который может заменить.
Все параметры конфигурации для могут быть предоставлены как переменные среды.
В проекте maven мы заменяем
maven-gpg-plugin
с участием:
<plugins>
<plugin>
<groupId>org.simplify4u.plugins</groupId>
<artifactId>sign-maven-plugin</artifactId>
<version><!-- check releases page --></version>
<executions>
<execution>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
В системе CI мы настраиваем переменные среды для сборки:
- SIGN_KEY - бронированный ключ GPG / PGP
- SIGN_KEY_ID - идентификатор ключа в шестнадцатеричном формате - если не указан, будет использован первый ключ из SIGN_KEY
- SIGN_KEY_PASS - кодовая фраза для расшифровки закрытого ключа
Также для
sign-maven-plugin
нам не нужны специальные профили для активации / деактивации подписи по умолчанию, если элементы конфигурации недоступны, плагин пропускает выполнение без ошибок.