Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何使用 gpg 签名验证 hugo 并部署 Github Pages

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

原创
作者头像
timerring
发布于 2024-12-18 10:12:29
发布于 2024-12-18 10:12:29
1210
举报
文章被收录于专栏:TechBlogTechBlog

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

中英文搜索引擎上都没找到对应的解决方法,翻了一下午文档我完成了这个功能,具体效果请见https://github.com/timerring/blog/commits/main/。这个解决方案首发在腾讯云开发者社区了,稍后会同步在我的英文博客(https://timerring.github.io/blog/posts)中,为了尽可能简洁,我省略了生成以及配置 git 上gpg密钥的过程,以及开启 github pages deploy 的过程,如有需要可以参考我博客的前几篇博文。

这周在忙着迁移自己的博客,恰巧知道了在 github 上会存在 commit 伪造的情况,因此安全起见,我添加了 gpg 签名,但是在部署 hugo 时仍然遇到了很多问题。

部署主要有两种情况:

  1. 直接将所有源文件 push 到 github 上,然后使用相关的 action 自己完成部署的全过程。
  2. 将博客源文件与 build 的文件隔离,每次 push 源文件到 github 的私有仓库里,然后在该私有仓库中设置相关的 actions workflow 完成向公开的静态仓库 push 并部署的过程。

为了更加安全,我选择了第二种方式,将 hugo 部署在 github pages 上的 workflow 里,需要使用到 actions-gh-pages 这个 action,但是由于种种原因这个 action 的作者在 issue 中说并不想添加 gpg 签名的功能。因此,只能自己动手丰衣足食。

导入 gpg 密钥

首先我从 github 上搜到了一个导入 gpg 密钥的 workflow,通过阅读文档,我自己使用的 workflow 如下所示:

代码语言:yaml
AI代码解释
复制
- name: Import GPG key
    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 }} # the fingerprint of the public subkey you use, if you use primary key, you can delete this line

其中,如果你只是用 gpg 的 primary secret key,则无需添加 fingerprint,安全起见我用主密钥生成了专门用于签名的 subkey,因此需要指定 subkey 对应的 public key 的 fingerprint。注意,填写 fingerprint 时需要删除中间的所有空格,否则会报错 67108933 Not implemented <GPG Agent>,我给对应的 issue 里添加了这个注意事项。

别忘记在仓库中填写对应的 secret 变量以及值。

部署

由于作者不打算添加 gpg 签名,因此我们需要自己 clone 项目并进行修改。通常在 commit 中使用 -S 选项来指定使用 gpg 签名,因此我找到该 workflow 中 commit 对应的函数,并添加了对应的 -S 选项。

请注意,自己修改后的 workflow 并不能直接使用,作者说明如下:

This action and my other actions do not provide the branch execution. I add the lib/index.js for only each release commit. After releasing, I delete it.

因此,我们仍需自己发布一个版本,在该项目中直接运行 ./release.sh,并且发布你编写的版本。之后就可以在 workflow 中引用你的版本了,我的 workflow 如下:

代码语言:yaml
AI代码解释
复制
- name: Deploy Web
    uses: timerring/actions-gh-pages@v5.0.0
    with:
        personal_token: ${{ secrets.PERSONAL_TOKEN }}
        external_repository: your_username/your_repository # your target repository
        publish_branch: main
        publish_dir: ./public
        user_name: ${{ secrets.USER_NAME }}
        user_email: ${{ secrets.USER_EMAIL }} # ATTENTION: 请务必添加你 github 验证的 email,安全起见,我使用验证邮箱后 github 为我生成的邮箱地址。
        commit_message: ${{ github.event.head_commit.message }}

注意,请务必添加你 github 验证后的 email,否则由于作者设置的默认参数 ${process.env.GITHUB_ACTOR}@users.noreply.github.com 只会生成 USERNAME@users.noreply.github.com 并不是 ID+USERNAME@users.noreply.github.com,github 历史遗留问题,详情参见这里,但是你的私钥中并没有该 uuid,因此是无法通过 gpg 验证。(即使你在 keys 中添加了该 uuid,由于该用户邮箱并没有经过 github 验证,最后也只会显示 unverified)。

简单地讲,如果你的 github 账号是在 July 18, 2017 之后创建的,那么你的 github 邮箱地址就是 ID+USERNAME@users.noreply.github.com,而并非默认的 USERNAME@users.noreply.github.com。此时你就需要指定 user_email 参数并且填写你验证后的邮箱地址。

最后,push 到 blogsource 仓库后,该 workflow 会自动部署在 blog 仓库中,并且 commit 经过了 gpg 的签名显示 verified

附件

如果你也需要我的部署方法,可以直接使用我修改后发布的 action 版本,仓库地址 timerring/actions-gh-pages,参考我完整的 workflow yaml,别忘记填写对应的 secret 变量以及值:

代码语言:yaml
AI代码解释
复制
name: deploy

on:
    push:
        branches:
            - main
    workflow_dispatch:

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout
              uses: actions/checkout@v3
              with:
                  submodules: true
                  fetch-depth: 0
                  ref: main

            - name: Setup Hugo
              uses: peaceiris/actions-hugo@v2
              with:
                  hugo-version: "0.108.0"
                  extended: true

            - name: Build Web
              run: hugo --minify

            - name: Import GPG key
              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 }} # the fingerprint of the public subkey you use

            - name: Deploy Web
              uses: timerring/actions-gh-pages@v5.0.0
              with:
                  personal_token: ${{ secrets.PERSONAL_TOKEN }}
                  external_repository: your_username/your_repository # your target repository
                  publish_branch: main
                  publish_dir: ./public
                  user_name: ${{ secrets.USER_NAME }}
                  user_email: ${{ secrets.USER_EMAIL }} # ATTENTION: 请务必添加你 github 验证的 email,安全起见,我使用验证邮箱后 github 为我生成的邮箱地址。
                  commit_message: ${{ github.event.head_commit.message }}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档