重写了用来持续部署的 Workflow

重写了用来持续部署的 Workflow

引言

我的 博客 有三个主力镜像:

国内镜像部署在香港的主机,使用国内的图床[1];海外镜像部署在 Cloudflare Workers[2][3][4],使用 Cloudflare Workers 反代 GitHub 作为图床[5]

我的 博客 源码放在 GitHub 的 kukmoon_blog 仓库里,每次推送使用 GitHub Actions 进行持续部署。

我需要在部署时,不但要将静态页面分别部署到国内镜像和海外镜像,还要将图片从 GitHub 同步到国内图床,还要修改 MarkDown 源文件或者静态网页文件中的图片 URL。

再加上我用了 abbrlink 插件用于生成短链接,它需要在 hexo g 后修改 MarkDown 源文件,还需要推送回 GitHub repo,这样就让持续部署的工作更加复杂。

我之前用于持续部署的 GitHub Action Workflow 庞大、复杂、麻烦、低效,所以我又重新写了一个。

GitHub Actons Workflow 源码

流程

我在 Workflow 中设计了两个 Job,如下:

Job 1


graph TD
    A("检出 #40;获取博客源码和主题#41;") --> B(用 Node.js 12 渲染)
    B --> C(安装 Hexo-cli)
    C --> D(安装 Hexo 的依赖)
    D --> E(配置环境)
    E --> F(生成静态页面文件)
    F --> G("生成后更新博客源码#65292;用于添加 abbrlink")
    G --> H(缓存 Wrangler)
    H --> I(部署到 Cloudflare Workers)
    I --> J(部署到 GitHub Pages)
    J -.-> J1(进一步部署到 Cloudflare Pages 或 Netlify 等)
    J ---> K("部署到使用 CPanel 的虚拟主机 
#40;其中包括修改静态网页文件中的图片 URL #65292;改成国内图床的#41;")

Job 2


graph TD
  A("检出 (获取图床 repo 中的图片)") --> B(推送到 CODING) --> C(推送到码云)

Mermaid 流程图居然不支持特殊符号,包括部分英文标点符号和全部中文标点符号,一定要用转义字符并且用英文双引号引起来才行,否则无法渲染。

源码

注意源码中引用的 GitHub Secrets。

参考文献:[1][2][3][4][5][6][7][8][9][10][11]

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
name: CI

# 只监听 master 分支的改动
on:
push:
branches:
- master

# 自定义环境变量
env:
GIT_USER: Kukmoon
GIT_EMAIL: kukmoon97@gmail.com
VHOST_NAME: kukmoonx
VHOST_IPv4: 999.999.999.999


# 每个 jobs 分别同时在独立的虚拟机中运行
jobs:
deploy_to_All:
# 1. Build
# 2. Deploy to GitHub pages, and then checkouted and deployed to CF Pages
# 3. Deploy to CF Workers
# 4. Replace URLs of images and deploy to the Web hosting service using CPanel

name: Build'n'deploy
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest]
node_version: [12.x]

steps:
# 检出(获取博客源码和主题)
- name: Checkout
uses: actions/checkout@v2
# 用 checkout 检出仓库,是把仓库里所有的文件,保存到了虚拟主机的 /home/runner/work/kukmoon_blog/kukmoon_blog 目录,
# 这个目录对应的环境变量是 $GITHUB_WORKSPACE
# 可以直接在这里执行 git push,推送到其他的远端仓库
# 如果有子模块(例如主题),需要设置 with: submodules: 'true'。我已经不用子模块了,姑且跳过。

# 用 Node.js 12 渲染
- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node_version }}

# 安装 Hexo-cli
- name: Install hexo
run: |
npm install -g hexo-cli

# 安装依赖
- name: Install hexo with dependencies
run: |
npm install

# 配置环境(用于通过SSH协议部署到GitHub和虚拟主机)
- name: Configuration environment
env:
HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
run: |
sudo timedatectl set-timezone "Asia/Shanghai"
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# 从 GitHub 获取公钥并保存到 known_hosts 文件
ssh-keyscan github.com >> ~/.ssh/known_hosts
# 从我的虚拟主机获取公钥保存到 known_hosts 文件
ssh-keyscan ${VHOST_IPv4} >> ~/.ssh/known_hosts
git config --global user.name $GIT_USER
git config --global user.email $GIT_EMAIL

# 生成静态页面文件
- name: Generate hexo
run: |
hexo clean
hexo g

# 生成后更新博客源码,用于添加 abbrlink
- name: Update Blog
run: |
# 检测 `source` 目录中的文件内容是否更改
git diff --quiet HEAD master -- ./source
# 如果没有更改就略过,如果有更改就添加、提交并推送
if [ $? -eq 0 ]; then
echo "nothing to update."
else
git add ./source
git commit -m "triggle by commit ${GITHUB_SHA}"
git push
fi

# 缓存 Wrangler。Wrangler 在构建时会在 workers-site 目录下执行 npm i,因此也要缓存这里的 node_modules。本步骤会在 $WORKSPACE 目录下写入内容,会被推送回 repo,所以要把本步骤放在 `Update Blog` 后面。
- name: Cache workers-site/node_modules
uses: actions/cache@v1
env:
cache-name: workers-site-node-modules
with:
path: workers-site/node_modules
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('workers-site/package-lock.json') }}

# 部署到 Cloudflare Workers
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@1.1.0
with:
apiToken: ${{ secrets.CF_WORKERS_TOKEN }} # 前一步设置的 Secrets 的名称
# Wrangler Action 也支持使用传统的 Global API Token + Email 的鉴权方式,但不推荐

# 部署到 GitHub Pages
- name: Deploy to GitHub Pages
run: |
cd ${GITHUB_WORKSPACE}/public
git init
git config --global user.name $GIT_USER
git config --global user.email $GIT_EMAIL
git add .
git commit -m "Deploy to GitHub Pages at $(date +'%Y-%m-%d %H:%M:%S')"
git push --force git@github.com:Kukmoon/kukmoon.github.io.git

# 部署到使用 CPanel 的虚拟主机
- name: Deploy to Virtual Host using CPanel
run: |
scp ${GITHUB_WORKSPACE}/.github/script/rebuild_repo.sh ${VHOST_NAME}@${VHOST_IPv4}:/tmp/rebuild_repo.sh # 重建远程主机的仓库
ssh ${VHOST_NAME}@${VHOST_IPv4} 'chmod +x /tmp/rebuild_repo.sh;/bin/sh /tmp/rebuild_repo.sh blog' # 重建远程主机的仓库
cd ${GITHUB_WORKSPACE}/public
git config --global user.name $GIT_USER
git config --global user.email $GIT_EMAIL
sed -i 's/https:\/\/img.kukmoon.com/https:\/\/kukmoon.coding.net\/p\/blog\/d\/img\/git\/raw\/master/g' `grep https:\/\/img.kukmoon.com -rl ./*.html` # 修改图床的 URL
sed -i 's/https:\/\/img.kukmoon.com/https:\/\/kukmoon.coding.net\/p\/blog\/d\/img\/git\/raw\/master/g' `grep https:\/\/img.kukmoon.com -rl ./*.xml` # 修改图床的 URL
git add .
git commit -m "Deploy to Virtual Host at $(date +'%Y-%m-%d %H:%M:%S')"
git push --force ssh://${VHOST_NAME}@${VHOST_IPv4}/home/kukmoonc/public_html/blog
scp ${GITHUB_WORKSPACE}/.github/script/delete_obj.sh ${VHOST_NAME}@${VHOST_IPv4}:/tmp/delete_obj.sh # 清理远程主机仓库的 .git/objects 目录
ssh ${VHOST_NAME}@${VHOST_IPv4} 'chmod +x /tmp/delete_obj.sh;/bin/sh /tmp/delete_obj.sh blog'


sync_img_host_to_other_img_hosts:
name: Sync image from GitHub 2 other img hosts
runs-on: ubuntu-latest
steps:
# 检出(获取图床 repo 中的图片)
- name: Checkout
env:
GITHUB_IMGHOST: Kukmoon/img
run: |
git init
git remote add origin https://github.com/${GITHUB_IMGHOST}.git
git fetch --all
for branch in `git branch -a | grep remotes | grep -v HEAD`; do
git branch --track ${branch##*/} $branch
done
git config --global user.name $GIT_USER
git config --global user.email $GIT_EMAIL


# 推送到 CODING
- name: Push to Coding
env:
CODING_USER: ${{ secrets.CODING_USER }}
CODING_TOKEN: ${{ secrets.CODING_TOKEN }}
run: |
git push --all --force https://${CODING_USER}:${CODING_TOKEN}@e.coding.net/kukmoon/blog/img.git
# coding_repo="https://${CODING_USER}:${CODING_TOKEN}@e.coding.net/kukmoon/blog/img.git"
# git remote add coding1 "${coding_repo}"
# git show-ref
# git branch --verbose
# git push --all --force coding1
# git push --tags --force coding1

# 推送到码云
- name: Push to Gitee
env:
GITEE_USER: ${{ secrets.GITEE_USER }}
GITEE_TOKEN: ${{ secrets.GITEE_TOKEN }}
run: |
git push --all --force https://${GITEE_USER}:${GITEE_TOKEN}@gitee.com/kukmoon/img.git
# gitee_repo="https://${GITEE_USER}:${GITEE_TOKEN}@gitee.com/kukmoon/img.git"
# git remote add gitee1 "${gitee_repo}"
# git show-ref
# git branch --verbose
# git push --all --force gitee1
# git push --tags --force gitee1

# 推送到使用 CPanel 的虚拟主机
- name: Push to vhost
env:
HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
run: |
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# 从我的虚拟主机获取公钥保存到 known_hosts 文件
ssh-keyscan ${VHOST_IPv4} >> ~/.ssh/known_hosts
git push --all --force ssh://${VHOST_NAME}@${VHOST_IPv4}/home/kukmoonc/public_html/img_host

图片版权

题图:GitHub Actions 的著作权、商标权等权利归 GitHub 所有。

头图:Banner Image by milkusmaximus from Pixabay

参考文献


求扫码打赏
“我这么可爱,请给我钱 o(*^ω^*)o”

重写了用来持续部署的 Workflow
https://blog.kukmoon.com/bb1e6cd29c02/
作者
Kukmoon谷月
发布于
2022年4月9日
许可协议