Github + Hexo 自动同步部署,一次酣畅淋漓的 Actions 实战
前言
继上一次实践出真知,学会了使用cron schedule定时启动Actions。我觉得把实践过程记录下来也挺好玩的。
此次目标:
我有两个博客仓库,一个为Github Pages服务Zarijaden.github.io,另一个由于改名会出大问题,只为Cloudflare Pages服务blog。
让我的 Hexo 博客仓库定期同步上游更新,同时保证自己的部署流程不被破坏。
下面是完整复盘。
一、开局翻车:拼错仓库名
最早我使用的是AI推荐的 Fork-Sync Action:
uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
结果第一条报错就。。。出师不捷啊:
1 2
| remote: Repository not found. fatal: repository 'https://github.com/Zarijaden/blig.git/' not found
|
原因非常尴尬:
我把
“blog” 拼成了
“blig”。。。
二、GitHub 不能 fork 自己
我一直觉得反正库的内容一样,那凭啥没法同步呢?但实际上忽略了一条硬性规则:
GitHub 不允许 fork 自己的仓库。
于是下面这行条件从一开始就注定失败:
if: ${{ github.event.repository.fork }}
Actions 的表现也很诚实:
Job skipped
删掉这行后,工作流终于开始运行。
仓库名对了,fork 条件也删了,但紧接着迎面撞上 Git 的核心哲学:
fatal: refusing to merge unrelated histories
原因很简单:
- 我的仓库不是 GitHub 意义上的 fork
- 历史树是独立创建的
- upstream 和本地完全没有共同祖先
Fork-Sync Action 本质上是:
git merge upstream/main
没有血缘关系?
直接拒绝。
四、暴力破局:reset –hard
既然 merge 走不通,那就换个思路:
直接让两个仓库在完全一致。
于是我下了狠手:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| name: Upstream Reset
on: workflow_dispatch:
permissions: contents: write
jobs: reset: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.SYNC_TOKEN }}
- name: hard reset to upstream/main run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com"
git remote add upstream https://github.com/Zarijaden/blog.git || true git fetch upstream
git reset --hard upstream/main git push origin main --force
|
效果非常震撼:
✅ 提交历史完全一致
✅ 没有任何 upstream 残留痕迹
✅ 两个仓库像是从同一个模板刻出来的
代价是:
我自己的 workflow ,以及它的提交历史被一起抹掉了。
五、最后阴险的隐藏坑
我以为 Git 层面的问题已经全部解决,结果日志又给了我一巴掌:
、
Input required and not supplied: token
、
当时我的第一反应是:
???我明明生成了 PAT 啊???
真相非常冷酷
我在 workflow 里写的是:
1 2 3 4
| - uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.SYNC_TOKEN }}
|
但我 根本没有在仓库里创建这个 Secret。
也就是说:
- ✅ PAT 生成了
- ❌ 没放进仓库 Secrets
- ❌
“secrets.SYNC_TOKEN” 实际是
“undefined”
GitHub Actions 的规则非常严格:
找不到的 secret 不是空值,而是直接报错。
于是整个 job 在 checkout 阶段直接挂掉。
正确姿势
进仓库Settings → Secrets and variables → Actions
新建 Secret→
Name: SYNC_TOKEN
Value: ghp_xxxxxxxx
六、胜利了?
在所有历史对齐、权限问题解决之后,我用了这里这份workflow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| name: Upstream Sync & Hexo Deploy
permissions: contents: write pages: write id-token: write
on: schedule: - cron: "0 17 * * 5" push: branches: - main workflow_dispatch:
concurrency: group: pages cancel-in-progress: true
jobs: sync_with_upstream: name: Sync with Upstream runs-on: ubuntu-latest
steps: - name: Checkout target repo uses: actions/checkout@v3 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }}
- name: Sync Upstream uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 with: target_repo_token: ${{ secrets.GITHUB_TOKEN }} upstream_sync_repo: Zarijaden/blog upstream_sync_branch: main target_sync_branch: main test_mode: false
- name: Check for Failure if: failure() run: | echo "[Error] Upstream sync failed." exit 1
build-and-deploy: name: Hexo Deploy needs: sync_with_upstream runs-on: ubuntu-latest
steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: npm
- name: Install dependencies run: | npm install npx hexo --version
- name: Generate static files run: npx hexo generate
- name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public publish_branch: gh-pages force_orphan: true
|
现在再看这个绿油油的 Actions 面板,只有一个感觉:
酣畅淋漓,大获成功。
七、怎么还有!
分体设计 + 总体调度
一个星期后,我发现TMD又报错了!再次忠告,只要做好了同步工作流,下游仓库就不要再改动了,否则历史不一致就会同步冲突(conflict),报错。
接着接着,我发现一体设计的部署居然会迟一个版本,
原来啊,同一个 workflow run,用的是“触发时的代码快照”
也就是说:
- workflow 文件 在 job 开始前就被固定
- job A 改了 .github/workflows
- job B 仍然用旧的 workflow 定义
✅ 最终架构:三个 workflow
.github/workflows/
├── sync.yml # 只同步内容
├── deploy.yml # 只部署 Hexo
└── scheduler.yml # 总体调度
sync.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| name: Sync Upstream
on: workflow_dispatch
permissions: contents: write
jobs: sync: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.SYNC_TOKEN }}
- name: Sync upstream content only run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com"
git remote add upstream https://github.com/Zarijaden/blog.git || true git fetch upstream
git checkout upstream/main -- source git checkout upstream/main -- themes git checkout upstream/main -- _config.yml
git commit -am "Sync upstream content" || true git push
|
deploy.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| name: Hexo Deploy
on: workflow_dispatch:
permissions: contents: write pages: write id-token: write
concurrency: group: pages cancel-in-progress: true
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0
- uses: actions/setup-node@v4 with: node-version: 24 cache: npm
- run: npm install
- run: npx hexo generate
- uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public publish_branch: gh-pages force_orphan: true
|
scheduler.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| name: Scheduler
on: schedule: - cron: "0 17 * * 5" workflow_dispatch:
permissions: actions: write
jobs: trigger: runs-on: ubuntu-latest steps: - uses: benc-uk/workflow-dispatch@v1 with: workflow: sync.yml token: ${{ secrets.SYNC_TOKEN }}
- run: sleep 60
- uses: benc-uk/workflow-dispatch@v1 with: workflow: deploy.yml token: ${{ secrets.SYNC_TOKEN }}
|
先同步上游代码,等待仓库更新后再调用另一个action部署
嗯,目前没啥问题