通过 GitHub Actions 实现跨仓库 Blog 自动部署
背景
我把博客文章和网站代码放在了两个不同的 GitHub 仓库中:
- 一个仓库负责保存 Markdown 文章(
private repo); - 另一个仓库负责构建静态网站并发布到 GitHub Pages(
public repo)。
以前修改文章后,还需要手动进入网站仓库执行部署。于是我希望实现下面的流程:
博客目录发生文件变更并推送后,自动触发另一个仓库的 GitHub Pages 部署。
整体流程
方案选择
GitHub Actions 的 push 事件默认只作用于当前仓库。源仓库的 workflow 不能直接监听另一个仓库的变化,因此需要主动调用目标仓库的 workflow。
常见方案有两种:
- 使用
repository_dispatch发送自定义事件。 - 调用目标仓库已有的
workflow_dispatch。
我选择第二种方式。
目标仓库的部署 workflow 本身已经支持手动触发,因此源仓库只需要调用它,不需要复制或修改目标仓库的构建逻辑。
这样做的好处是:
- 改动范围小;
- 目标仓库的部署逻辑保持独立;
- 可以明确指定目标分支;
- 触发记录可以直接在目标仓库的 Actions 页面查看。
源仓库的 workflow
在源仓库中增加一个 workflow:
name: Trigger Blog Deployment
on: push: branches: - '<SOURCE_BRANCH>' paths: - '<BLOG_DIRECTORY>/**'
permissions: contents: read
jobs: trigger-deploy: runs-on: ubuntu-latest
steps: - name: Trigger target deployment env: GH_TOKEN: ${{ secrets.DEPLOY_TRIGGER_TOKEN }} run: | set -euo pipefail
if [ -z "$GH_TOKEN" ]; then echo "::error::Deployment token is not configured" exit 1 fi
gh workflow run "<TARGET_WORKFLOW_NAME>" \ --repo "<TARGET_REPOSITORY>" \ --ref "<TARGET_BRANCH>"这里的占位符分别表示:
<SOURCE_BRANCH>:源仓库需要监听的分支;<BLOG_DIRECTORY>:博客内容所在目录;<TARGET_REPOSITORY>:目标仓库;<TARGET_WORKFLOW_NAME>:目标部署 workflow 名称;<TARGET_BRANCH>:目标仓库执行部署的分支。
为什么不能直接使用 GITHUB_TOKEN
源仓库中的默认 GITHUB_TOKEN 通常只拥有当前仓库的权限。
如果使用它去调用另一个仓库的 workflow,可能会因为目标仓库权限不足而失败。因此这里使用一个只授权给目标仓库的 Fine-grained Personal Access Token。
建议权限保持最小:
Repository access: Only select repositories
Repository permissions: Actions: Read and write Metadata: Read-only然后把 Token 保存为源仓库的 Actions Secret:
DEPLOY_TRIGGER_TOKENToken 的真实值不应该写入代码、文章或日志中。
如何获取跨仓库部署 Token
在 GitHub 中进入 Developer settings -> Fine-grained personal access tokens,然后按下面的范围创建 Token:
Resource owner选择当前账号或目标组织。Repository access只选择目标仓库,不要选择所有仓库。- Repository permissions 设置为:
Actions:Read and write;Metadata:Read-only。
- 设置合理的过期时间,并记录后续轮换时间。
- 创建后立即复制 Token。Token 通常只显示一次,离开页面后不能再次查看原值。
这个 Token 只用于调用目标仓库的 Actions。不要把它写进仓库、workflow YAML、文章内容或日志,也不要为了读取其他私有仓库而顺手扩大 Repository access 范围。
如何配置 Token
在源仓库进入 Settings -> Secrets and variables -> Actions,创建一个 Repository secret:
Name:DEPLOY_TRIGGER_TOKEN;Secret:填入刚才生成的 Token。
workflow 中通过 ${{ secrets.DEPLOY_TRIGGER_TOKEN }} 读取它。也可以用 GitHub CLI 配置,命令中的仓库名仍然是占位符:
gh secret set DEPLOY_TRIGGER_TOKEN --repo SOURCE_OWNER/SOURCE_REPO命令会提示输入 Secret 值。不要把真实 Token 拼接到命令参数中,也不要用 echo 或调试模式输出 Token。
触发条件说明
使用 paths 过滤器可以避免无关文件变更触发部署:
paths: - '<BLOG_DIRECTORY>/**'只有博客目录发生变化时,源 workflow 才会运行。
以下变更会触发:
- 新增文章;
- 修改文章;
- 删除文章;
- 移动或重命名文章。
以下变更不会触发:
- 修改非博客目录;
- 修改本地编辑器配置;
- 修改与网站构建无关的文档。
如果一次 push 中包含多个博客文件,通常只会触发一次源 workflow,然后由这次 workflow 调用一次目标仓库部署。
目标仓库 workflow
目标仓库的部署 workflow 需要支持手动触发:
on: workflow_dispatch:收到调用后,目标仓库继续负责完整的部署流程:
- checkout 目标仓库代码和所需的源仓库内容;
- 安装静态网站依赖;
- 构建静态网站并上传 artifact;
- 使用
deploy-pages或目标仓库现有的 Pages 部署步骤发布到 GitHub Pages。
如果源仓库是私有仓库,目标 workflow 还需要单独具备读取源仓库的凭据。跨仓库触发 Token 只解决“启动目标 workflow”,不自动解决“目标 workflow 读取私有源内容”。
安全注意事项
- 源仓库 workflow 使用
permissions: contents: read,只授予当前任务需要的权限; - Token 只选择目标仓库,并只授予
Actions: Read and write和Metadata: Read-only; - 不要在 YAML、脚本、Issue、构建产物或日志中输出 Token;
- 为 Token 设置过期时间,定期轮换;
- 生产部署应由主分支的 push 触发;
- 不要让不可信的 Pull Request 代码运行在能够读取部署 Secret 的上下文中;
- 避免目标仓库再次回写会触发源 workflow 的内容,防止两个仓库之间形成循环触发。
总结
最终的自动化链路如下:
博客文章变更 ↓推送到源仓库 ↓路径过滤博客目录 ↓触发目标仓库 workflow ↓构建并部署 GitHub Pages这个方案不需要额外服务器,也不需要本地执行部署命令。通过路径过滤和最小权限 Token,可以在保持两个项目独立的同时,实现博客内容的自动发布。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!












