使用GPG签名部署Github Pages

本文也发布在我的博客上,最新修订内容可随时参考:使用GPG签名部署Github Pages

这周忙着迁移博客,偶然了解到GitHub存在提交伪造的风险,出于安全考虑给仓库添加了GPG签名。但在使用Hugo部署时,遇到了关于GPG签名能否在部署流程中生效的问题,好在最终解决了。

如果你还不了解GPG,可先阅读GPG入门指南

如何使用GPG签名部署并验证Github Pages

主流部署方式有两种:

  1. 直接将所有源文件推送到GitHub,通过官方Action完成构建部署。
  2. 将博客源文件与构建产物分离,源文件存放在私有仓库,通过Workflow自动构建并推送到公开的静态资源仓库。

为确保更高安全性,我选择了第二种方式,利用GitHub Pages的Workflow结合actions-gh-pages行动部署Hugo。但该行动作者明确表示不打算添加GPG签名功能,因此需要手动解决签名问题。

导入GPG密钥

首先在GitHub上找到一个导入GPG密钥的Workflow行动,参考文档后我的配置如下:

- name: 导入GPG密钥 # 将GPG密钥导入到GitHub Action环境  
  uses: crazy-max/ghaction-import-gpg@v6 # 行动仓库:https://github.com/crazy-max/ghaction-import-gpg  
  with: # 使用子密钥进行提交签名(若用主密钥,可参考行动文档)  
      gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} # GPG子私钥(加密存储的Secret)  
      passphrase: ${{ secrets.PASSPHRASE }} # 子密钥的密码短语  
      git_user_signingkey: true # 配置Git使用签名密钥  
      git_commit_gpgsign: true # 强制提交时使用GPG签名  
      fingerprint: ${{ secrets.FINGERPRINT }} # 所用子公钥的指纹(不带空格)  

注意:若仅使用GPG主私钥,无需指定fingerprint;但为安全起见,我生成了专门用于签名的子密钥,此时必须填写子公钥的指纹**(不带空格)**,否则会报错67108933 Not implemented <GPG Agent>。我已在相关Issue中补充了该注意事项。

别忘了在仓库的「 Secrets」中配置对应的密钥和密码变量。

自定义部署行动

由于官方行动不支持GPG签名,需克隆项目并修改代码。核心是在提交命令中添加-S选项以启用GPG签名。我在提交记录中找到提交逻辑,添加了-S参数。

需注意:官方行动不保留分支代码,每次发布后会删除修改,因此必须自行发布自定义版本。在项目根目录运行./release.sh生成新版本,之后即可在Workflow中引用。我的部署配置如下:

- name: 部署到Web  
  uses: timerring/actions-gh-pages@v5.0.0 # 基于官方行动修改的自定义版本(可直接使用)  
  with:  
      personal_token: ${{ secrets.PERSONAL_TOKEN }} # GitHub Action的个人令牌  
      external_repository: your_username/your_repository # 目标仓库(格式:用户名/仓库名)  
      publish_branch: main # 部署目标分支  
      publish_dir: ./public # 构建产物目录(Hugo默认输出路径)  
      user_name: ${{ secrets.USER_NAME }} # 提交者姓名(需与GPG密钥UID一致)  
      user_email: ${{ secrets.USER_EMAIL }} # 提交者邮箱(必须是GitHub验证过的邮箱)  
      commit_message: ${{ github.event.head_commit.message }} # 继承原始提交信息  

关键细节

  • 邮箱必须为GitHub验证过的地址:若使用默认值${process.env.GITHUB_ACTOR}@users.noreply.github.com,会导致邮箱与GPG密钥中的UID不匹配(2017年后创建的账号实际邮箱为ID+USERNAME@users.noreply.github.com),最终签名显示unverified。即使在密钥中添加该UID,未经验证的邮箱仍无法通过GitHub校验。

部署完成后,向源仓库(如blogsource)推送代码,Workflow会自动构建并推送到目标仓库(如blog),所有提交均会附带GPG签名并显示verified
验证效果可参考我的仓库提交记录

附录:完整Workflow示例

如需复用我的Hugo部署方案,可直接使用自定义行动timerring/actions-gh-pages,并按以下YAML配置Workflow(注意替换secrets和仓库名):

name: 博客部署  

on:  
  push:  
    branches:  
      - main  # 监听主分支推送  
  workflow_dispatch:  # 支持手动触发  

jobs:  
  build:  
    runs-on: ubuntu-latest  
    steps:  
      - name: 拉取代码  
        uses: actions/checkout@v3  
        with:  
          submodules: true  # 包含子模块(如主题)  
          fetch-depth: 0     # 获取完整提交历史  
          ref: main          # 拉取主分支代码  

      - name: 安装Hugo  
        uses: peaceiris/actions-hugo@v2  
        with:  
          hugo-version: "0.108.0"  # 指定Hugo版本  
          extended: true           # 启用扩展版本(支持SCSS等)  

      - name: 构建网站  
        run: hugo --minify         # 生成压缩后的静态文件  

      - name: 导入GPG密钥  
        uses: crazy-max/ghaction-import-gpg@v6  
        with:  
          gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}  
          passphrase: ${{ secrets.PASSPHRASE }}  
          git_user_signingkey: true  
          git_commit_gpgsign: true  
          fingerprint: ${{ secrets.FINGERPRINT }}  

      - name: 部署到GitHub Pages  
        uses: timerring/actions-gh-pages@v5.0.0  
        with:  
          personal_token: ${{ secrets.PERSONAL_TOKEN }}  
          external_repository: timerring/blog  # 目标仓库:你的用户名/仓库名  
          publish_branch: main                 # 部署到主分支  
          publish_dir: ./public                # 构建产物目录  
          user_name: "GitHub Action"           # 提交者姓名(任意,但需与GPG密钥UID兼容)  
          user_email: ${{ secrets.USER_EMAIL }} # 必须为GitHub验证邮箱  
          commit_message: "[skip ci] ${{ github.event.head_commit.message }}"  

通过以上配置,即可在GitHub Pages部署流程中实现GPG签名验证,确保代码提交的真实性和完整性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

timerring

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值