如何在Github Actions中使用GPG密钥?

24

我正在尝试通过GitHub actions进行maven部署,但是我遇到了以下错误:

gpg: directory '/home/runner/.gnupg' created
gpg: keybox '/home/runner/.gnupg/pubring.kbx' created
gpg: no default secret key: No secret key
gpg: signing failed: No secret key
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  13.272 s
[INFO] Finished at: 2020-04-06T12:18:44Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-gpg-plugin:1.5:sign (sign-artifacts) on project pretty-simple-jar: Exit code: 2 -> [Help 1]
我了解我需要以某种方式在虚拟运行程序中导入我的gpg秘钥,但是我无法通过GitHub actions工作流程在虚拟运行程序中导入我的秘钥。
下面是我的工作流程:
jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Maven Central Repository
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: Display settings.xml
        run: |
          echo "<settings><servers><server><id>ossrh</id><username>${{ secrets.OSSRH_USERNAME }}</username><password>${{ secrets.OSSRH_TOKEN }}</password></server></servers><profiles><profile><id>ossrh</id><activation><activeByDefault>true</activeByDefault></activation><properties><gpg.keyname>${{ secrets.GPG_KEY_ID }}</gpg.keyname><gpg.passphrase>'${{ secrets.GPG_PASSPHRASE }}'</gpg.passphrase></properties></profile></profiles></settings>" > /home/runner/.m2/settings.xml
          cat /home/runner/.m2/settings.xml
      - name: Build Maven Project
        run: mvn clean install
      - name: Publish to Apache Maven Central
        run: mvn deploy

请查看GitHub关于使用secrets的文章 - Madhu Bhat
5个回答

33

由于GitHub Actions基本上是运行命令的容器,您是否考虑过在项目中将您的密钥定义为秘密,并在Github Action定义中导入它?

以下是我之前在项目中使用的步骤,将生成的构件发布到Sonatype的暂存库:

  • 打开终端窗口。
  • 如果您不知道您的密钥ID,请通过电子邮件搜索:gpg --list-secret-keys user@example.com
  • 将您的密钥导出为Base64:gpg --export-secret-keys YOUR_ID_HERE | base64 > private.key
  • 在您的 Github 项目中,创建一个名为GPG_SIGNING_KEY 的新秘密,并粘贴您的密钥的Base64内容。
  • 在您的yml工作流文件中,包括一个步骤来从刚刚定义的秘密中导入密钥。
- name: Configure GPG Key
  run: |
    echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import
  env:
    GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}

目前为止,这种方法运行得非常好,虽然有一些限制我无法解决:

  • 您的 GPG 密钥不应受密码保护。我找不到一种在不要求输入密码的情况下导入受保护密钥的方法。
  • 我找不到一种方法来使用我的 GitHub GPG 密钥进行此过程。

以防万一,这里 有一个使用这种方法发布 Maven artifacts 的项目示例。不过,与上述步骤唯一的区别是将命令外部化到bash 脚本文件中。


只需尝试运行命令"gpg --batch --import ~/.gnupg/private.key" 导入受密码保护的密钥。我假设您在导入时不需要输入密码,只有在以后使用时才需要。 - André
谢谢您的回复,对我很有帮助。为了添加密码,我只是使用了这个回复,而不是您的第三行运行命令: echo your_password | gpg --batch --yes --passphrase-fd 0 your_file.gpghttps://unix.stackexchange.com/questions/60213/gpg-asks-for-password-even-with-passphrase - eduardohl

20

感谢大家的回应。我现在使用这个GitHub操作,使得整个过程更加简单:

步骤1:提取密钥。

gpg --list-secret-keys --keyid-format LONG
gpg --export-secret-keys --armor {your_keyId}

步骤2:将提取的GPG密钥和密码短语存储为secrets

步骤3:将此步骤包含在您的工作流程中

- name: Import GPG Key
  uses: crazy-max/ghaction-import-gpg@v1
  env:
     GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
     PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

你如何在没有密码的情况下使用 --export-secret-keys 命令?我无法找到一种方法来在工作流中导出私钥,因为它一直停留在输入密码的步骤。 - vgdub
将它们存储将在运行器虚拟机中创建.kbx文件,但如果您有密码短语,则无法使用它? - vgdub
您需要此密码短语才能导出它。您在创建密钥时定义了该密码短语,如果没有它,您将无法执行部署。 - Piotr Wittchen

19

添加一个新的答案,因为这个问题是关于在特定情况下在Maven部署中使用GPG密钥。

使用Maven时不需要手动导入

与此同时,setup-java操作支持一切,一切都预先设置好。文档中有一个示例

    - name: Set up Apache Maven Central
      uses: actions/setup-java@v3
      with: # running setup-java again overwrites the settings.xml
        java-version: 8
        distribution: 'temurin'
        cache: 'maven'
        server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml
        server-username: OSSRH_USERNAME # env variable for username in deploy
        server-password: OSSRH_TOKEN # env variable for token in deploy
        gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
        gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase

    - name: Publish to Apache Maven Central
      run: mvn deploy
      env:
        OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
        OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }}
        MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

请注意,setup-java操作会自动为您配置Maven的settings.xml文件,并从给定的存储密钥导入GPG密钥。
请注意,在setup-java期间,您仅配置环境变量的名称。也就是说,您需要在后续步骤中提供这些环境变量的(秘密)值,以便在使用它们时使用。

提示:如果您的环境名称不是默认值,则在脚本中设置属性环境非常重要,否则您将在过程中没有任何明显错误的情况下收到“无秘密密钥”的错误。 - Dubas
1
@Dubas 我也遇到了这个问题。你说的默认环境名称是什么意思?我应该在哪里设置环境属性呢? - Piotr Olaszewski
@Piotr Olaszewski 在您的项目设置>环境中。默认环境称为“main”,如果您创建了其他名称的环境,则需要在脚本中指定它。 - Dubas
在运行此工作流程时出现错误 'gpg: Sorry, no terminal at all requested - can't get input'。我看到有人说从pgp.conf中删除'--no-tty'可能会有帮助,但是在GitHub Actions中如何做到这一点呢? - undefined
@HugoBois 你可能想尝试使用 --pinentry-mode loopback,或者在配置你的 maven-gpg-plugin 时,将 <gpgArguments><arg>--pinentry-mode</arg><arg>loopback</arg></gpgArguments> 添加到 <configuration> 中。 - undefined
是的,我已经完成了:https://shorturl.at/bluMP。我正在使用一个配置文件来激活maven-gpg-plugin,这可能是问题所在吗?我觉得很奇怪,GitHub actions setup-java不能提供私钥和密码... - undefined

2
您可以使用另一个插件https://www.simplify4u.org/sign-maven-plugin/来为工件签名。 sign-maven-plugin从环境变量中获取签名密钥和其余配置项,无需特殊配置。
另一个优点是sign-maven-plugin不需要使用配置文件来激活或停用插件,因为当插件未设置签名密钥时,插件会跳过执行而不报错。

0
我想出了以下解决方案(请参见此处
steps:
  - name: Import GPG key
    run: echo $GPG_KEY | base64 --decode | gpg --batch --import
    env:
      GPG_KEY: ${{ secrets.GPG_KEY }}

  - name: Add the custom gpg siging program that passes the passphrase to the gpg CLI
    run: |
      rm -rf /tmp/gpg.sh
      echo '#!/bin/bash' >> /tmp/gpg.sh
      echo 'gpg --batch --pinentry-mode=loopback --passphrase $GPG_KEY_PASSPHRASE $@' >> /tmp/gpg.sh
      chmod +x /tmp/gpg.sh

  - name: Setup git
    run: |
      git config commit.gpgsign true
      git config user.signingkey $GPG_KEY_ID
      git config gpg.program /tmp/gpg.sh
    env:
      GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}

1
目前您的回答不够清晰,请[编辑]以添加更多细节,帮助其他人了解它如何回答所提出的问题。您可以在帮助中心找到有关如何撰写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接