前
很长时间没有更新自己的博客了,可能是人的经验是有限的,也可能是最近的东西都是零散的记录在 Obsidian上。但是看过一篇写PKM的文章,所有的知识有 输入 转化 和输出 三个步骤。写博客就是属于输出的过程。
知识没有体系则不是知识
这篇文章里面,把自己的hugo的博客换了主题。觉得之前的 Paper-mod 的主题layout并不是很喜欢。
并且配置太多,不符合我现在的minimal的主张了。所以找到了一个 texify3
的主题,由于没有搜索功能,后面也进行了二次开发。加上一些自己喜欢的功能。后面可能会把这个主题从原来的 仓库中分离出来。
这篇看标题是记录把静态博客从 vercel 迁移到使用 Github action来进行部署。原因有
- vercel 在部署的时候 sass 有兼容性问题,导致css 无法完成编译。直接导致无法使用
- 显然 gtihub action 更是正规军,有完整的 CICD的流程。可以联系下新技能
在方案选型上使用:
- Hugo
- github Action
- Cloudflare R2
由于 Github Pages 只支持 Public 的仓库,但是博客的源文件不想open掉,所以这里使用 R2 来作为静态文件的托管。也遇上了一些问题。后面会讲。
正文
流水线
这里使用的是 Github Action。通过自己编写 yaml 文件来实现自动化的build和deploy。这里分两部分来介绍
Build
这里直贴出来pipeline 的文件,下面部份 是实现了 hugo 的安装,npm 安装依赖,以及Hugo 的编译。这里的 ShortID 是一个 博客的前缀路径,用于区分 对象存储里的文件版本。
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.126.1
steps:
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Install Dart Sass
run: sudo snap install dart-sass
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Node.js dependencies
run: npm install
- name: Install Node.js dependencies
run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
- name: Build with Hugo
env:
# For maximum backward compatibility with Hugo modules
HUGO_ENVIRONMENT: production
HUGO_ENV: production
run: |
hugo --minify --baseURL "${{ vars.BASE_URL }}/${{ env.SHORTID }}"
这里说一下ShortID,这里在流水线中生成了 ShortID, 在两个地方用到。
- 在Hugo 编译的时候配置在 baseURL中,用于访问不同的博客版本
- 写入临时文件,传递给下一个JOB(deploy)来使用
- name: Generate shortid
run: |
npm install shortid
SHORTID=$(node -e "console.log(require('shortid').generate())")
echo "SHORTID=$SHORTID" >> $GITHUB_ENV
- name: Print shortid
run: |
echo ${{ env.SHORTID }}
echo $SHORTID > ./public/shortid.txt
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: public-folder
path: ./public
Deploy
Deploy主要实现的功能就是上传到 R2。代码如下,使用 download-artifact 来获取前面的 public 文件夹。之后使用 upload 模块来上传到R2 即可提供访问。
# Deployment job
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download public folder artifact
uses: actions/download-artifact@v4
with:
name: public-folder
path: public/
- name: Read shortid from file
run: |
SHORTID=$(cat public/shortid.txt)
echo "SHORTID=$SHORTID" >> $GITHUB_ENV
- uses: shallwefootball/s3-upload-action@master
name: Upload public
with:
endpoint: ${{ vars.S3_ENDPOINT }}
aws_key_id: ${{ vars.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
aws_bucket: ${{ vars.AWS_BUCKET }}
source_dir: './public'
destination_dir: ${{ env.SHORTID }}
但是在实际使用的时候遇到了问题:
- R2 的文件版本问题
- R2 不支持try index.html
Patch
部署
第一个问题,我们在前面引入了 ShortID。
每次静态文件都会上传到不同的ShortID 对应的目录下。来实现版本控制。
针对第二个问题,使用一个简单的index文件来实现自动跳转到ShortID 的路径
- name: Create index.html
run: |
echo "<html><head><meta http-equiv='refresh' content='0; url=/${{ env.SHORTID }}/index.html'></head><body></body></html>" > index.html
访问
在R2 时候还有一个访问的问题。例如下面的链接。会报404的问题,因为不会自动try index.html
https://blog3.12ms.xyz/52UkBhSCH/posts/
这里需要在 CF中添加重定向规则,这样就强制在非资源链接后面添加 index.html 的文件名,例如上面的链接就变成了下面的样子。 这样就可以解决掉404 问题。
https://blog3.12ms.xyz/52UkBhSCH/posts/index.html
#匹配
(not http.request.uri.path contains "." and http.request.uri.path ne "/" and http.host eq "blog3.12ms.xyz")
#重定向
concat(http.request.uri.path, "/index.html")
后
虽然整体的过程没有什么难以理解的概念。但是从 vercel 升级到 GA 来进行部署 更贴近正式的 CICD 的流程还是很开心的。
中间遇到了一些问题,也是用综合的知识来进行一一解决。这就是工程师的成长之路吧。