自动部署
# 通过Github Action自动构建并部署项目
每次修改博客后都需要执行脚本deploy.sh,重新构建才能上传的github。
了解到GitHub的Action后,我想是否可以直接把整个项目上传到github的一个分支pages-code
(从main分支新建一个分支)上,再通过workflow自动将项目的代码构建并部署到指定GitHub Page的分支cy-pages
上,(如果有自己的服务器也可以部署到服务器上,可以参考这篇文章 (opens new window))
而且如果Action执行失败还会发qq邮箱通知,不用担心构建失败不知道。
在项目根目录创建文件.gitignore,推送时忽略node_modules目录,因为node_modules是一些三方依赖很大,而且可以在workflow中安装
node_modules/
仍然在.github/woorkflows/目录中创建新的workflow脚本deploy.yml
name: Deploy VuePress to GitHub Pages
# 当 pages-code 分支有 push 事件时触发
on:
push:
branches:
- pages-code
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# 检出代码
- uses: actions/checkout@v3
# 使用action库,安装node
- name: Set up Node.js # 使用action库 actions/setup-node安装node
uses: actions/setup-node@v3
with:
node-version: 16 # 根据你的项目需求选择 Node.js 版本
# 安装依赖
- name: npm install
run: npm install
# 构建 VuePress 项目,并将workflow拷贝到dist中用于仓库同步到gitee
- name: Build VuePress
run: npm run docs:build
# 复制 CNAME 文件到 dist
- name: Copy NAME to dist
run: cp ./CNAME ./docs/.vuepress/dist/
# 复制同步工作流syncToGitee 到 dist
- name: Copy .github to dist
run: |
mkdir -p ./docs/.vuepress/dist/.github/workflows
cp ./.github/workflows/syncToGitee.yml ./docs/.vuepress/dist/.github/workflows/
# 部署到 GitHub Pages
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} # 在github生成PERSONAL_ACCESS_TOKEN
publish_dir: ./docs/.vuepress/dist # VuePress 默认的输出目录
publish_branch: cy-pages # 部署到的目标分支
exclude_assets: ""
# #部署到服务器
# - name: Deploy to Staging My server
# uses: easingthemes/ssh-deploy@v2.1.6
# env:
# # 使用GitHub仓库里的secret设置的值
# SSH_PRIVATE_KEY: ${{ secrets.MY_SERVER_PRIVATE_KEY }}
# # 源目录,编译后生成的文件目录
# SOURCE: './docs/.vuepress/dist/'
# #服务器公网地址
# REMOTE_HOST: ${{ secrets.MY_SERVER_IP }}
# #服务器用户名-一般默认root
# REMOTE_USER: 'root'
# #服务器中,代码部署的位置
# TARGET: '/opt/myblog'
# #去除的文件
# EXCLUDE: "/dist/, /node_modules/"
这里简单说明下文件的内容
- 第一行:本次workflow的名字,可自行更换
- 第 3~6 行:说明只有当 pages-code分支有提交到远程库(push)的时候,执行本次workflow
- 第 8 行:jobs,本次我们只用了一个 job,也就是第 9 行的 job
- 第 10 行:指定要在哪个操作系统的环境下编译出包(一般是 Linux)
- 接下来就是 deploy 这个 job 的 steps,每个 step 做了不同的事情,例如安装 node,然后安装依赖和执行构建命令
- 第 31 行开始就是一些环境变量的设置,例如读取我们上一小节设置的 IP 和私钥信息
注意:
因为workflow需要放在对应分支下才能被触发,pages-code分支触发事件push时,GitHub Actions 会检查该分支当前提交中是否存在对应的 YAML 文件,才会执行,所以需要把syncToGitee.yml文件复制到 dist目录
github_token:
- 生成个人访问令牌 (PAT):
- 在GitHub的 Settings > Developer settings > Personal access tokens->token classic。
- 创建一个新的 token (classic),确保选中了
repo
和workflow
权限。 - 复制生成的令牌。
- 将 token 添加到 Secrets:
- 在你的 GitHub 仓库中,进入 Settings > Secrets and variables > Actions。
- 添加一个新的 Repository Secret,名称为
PERSONAL_ACCESS_TOKEN
,值为刚刚生成的 PAT。
- 生成个人访问令牌 (PAT):
publish_dir: 就是你要复制到目标分支cy-pages的目录
exclude_assets: 指定哪些文件或目录不推送到目标分支,exclude_assets的值默认有**
.github
**
# 优化自动部署
每次等待构建并部署都需要等2分钟甚至更久,这是因为每次执行workflow都需要重新搭建环境npm install
,GitHub Action 提供了缓存机制,可以不用每次都搭建环境。修改deploy.yml文件
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# ...
# 添加缓存
# 缓存 node_modules
- name: Cache node_modules
id: cache-node-modules
uses: actions/cache@v3
with:
path: node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
node-modules-${{ runner.os }}-
# 安装依赖(仅在缓存未命中时执行)
- name: npm install
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm install
# ...
解释(由于带${{ }}部署项目时会被node解析,所以写在代码块里)
path: node_modules
表示要缓存项目的 node_modules 文件夹
key: node-modules-${{ runner.os }}-${{ hashFiles('\**/package-lock.json') }}
node-modules-: 这是一个固定的前缀,用来标识缓存的内容是 `node_modules`。
${{ runner.os }}: 表示当前运行的操作系统(如 `ubuntu-latest`, `windows-latest`, `macos-latest`)。
${{ hashFiles('**/package-lock.json') }}: 基于 `package-lock.json` 文件的内容生成一个哈希值。如果 `package-lock.json 发生变化(例如添加或更新依赖),哈希值也会变化,从而触发新的缓存。
restore-keys: |
node-modules-${{ runner.os }}-
作用: 提供一组备用的缓存键(`restore-keys`),用于在主键(key)未命中时尝试部分匹配。
分解解释:
|:YAML 的多行字符串语法,表示后面的每一行是一个独立的 restore-key。
node-modules-${{ runner.os }}-: 这是一个“模糊匹配”的键,只包含固定前缀和操作系统信息,而不包含 `package-lock.json 的哈希值。如果主键(key)未命中,GitHub Actions 会依次尝试包含这些前缀的缓存:
可以看到workflow的运行时间,因为命中缓存跳过了执行npm install
的40秒
这样deploy.sh脚本就没用了,以后都是由GitHub Action自动帮我们部署
# 优化bug
细心的读者肯定发现我们的最后更新时间比我们修改的时间早了8个小时,而且所以文章的更新时间都是一样的
早8个小时是因为我们是用GitHub action的服务器部署项目的,而LastUpdated是根据git log设置的,GitHub服务器的时区早我们8个小时,导致在Github上的git log也早了8个小时,只要修改GitHub服务器的时区就行
文章的更新时间都是一样的是因为,我们代码的问题,我们使用的插件 actions/checkout@v3默认是浅拷贝,也就是获取最近一次推送的记录,所以应该获取全部的推送记录,即获取完整的.git(git log是根据.git获取的),就能有正确的更新时间了
修改deploy.yml
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# 检出代码
- uses: actions/checkout@v3
with:
fetch-depth: 0 # 获取完整的历史记录(包括 .git 文件夹)
- name: Set timezone
run: echo "TZ=Asia/Shanghai" >> $GITHUB_ENV # 替换为你的时区
参考: