Избегайте запроса подписи 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 нам не нужны специальные профили для активации / деактивации подписи по умолчанию, если элементы конфигурации недоступны, плагин пропускает выполнение без ошибок.

Другие вопросы по тегам