GitHub Actions自动化部署

什么是 GitHub Actions

  • 定义: GitHub 内置的自动化工作流平台,支持 CI(持续集成)/CD(持续部署)。
  • 组成:
    • workflow(工作流程): 持续集成一次运行的过程,就是一个 workflow(.github/workflows 下的 yml 文件)
    • job(任务): 一个 workflow 由一个或多个 jobs 构成,含义是一次持续集成的运行,可以完成多个任务。
    • step(步骤): 每个 job 由多个 step 构成,一步步完成。
    • action(动作): 每个 step 可以依次执行一个或多个命令(action)。

基本结构

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
# name字段是 workflow 的名称。如果省略该字段,默认为当前 workflow 的文件名。
name: My Workflow

# on字段指定触发 workflow 的条件,通常是某些事件。上面代码指定,push事件触发 workflow。
# on字段也可以是事件的数组。
on字段也可以是事件的数组。
on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 2 * * *' # 每天 UTC 2:00
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'

# 该步骤所需的环境变量
env:
NODE_VERSION: '18.x'
DEPLOY_ENV: production

# jobs 是 workflow 文件的主体,表示要执行的一项或多项任务。jobs字段里面,需要写出每一项任务的job_id,具体名称自定义。job_id里面的name字段是任务的说明。
jobs:
# 任务
build:
runs-on: ubuntu-latest # runs-on:指定运行所需要的虚拟机环境。必填字段
timeout-minutes: 30 # 任务默认超时时间
steps:
- name: Checkout
uses: actions/checkout@v4

on(触发条件)常见写法

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
# 1) 简写:push 即触发
on: push

# 2) 多事件
on: [push, pull_request]

# 3) 限定分支/标签
on:
push:
branches: [ main ]
tags: [ 'v*' ]

# 4) Star 触发
on:
watch:
types: [started]

# 5) 定时(每小时)
on:
schedule:
- cron: "0 * * * *"

# 6) 手动触发并带输入
on:
workflow_dispatch:
inputs:
env:
description: '部署环境'
required: true
default: 'prod'

jobs(任务)关键点

  • runs-on: 运行环境(必填)
    • 支持:ubuntu-latest, windows-latest, macos-latest
  • needs: 依赖其它 job(控制顺序)
  • timeout-minutes: 任务超时(默认上限 360 分钟)
  • 并行/串行: 默认并行;用 needs 串行化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
jobs:
first_job:
name: First
runs-on: ubuntu-latest
steps:
- run: echo "I am first"

second_job:
name: Second
needs: first_job
runs-on: macos-latest

third_job:
name: Third
needs: [first_job, second_job]
runs-on: windows-latest

steps

steps字段指定每个 Job 的运行步骤,可以包含一个或多个步骤。每个步骤都可以指定name、run、env、id、uses、with、continue-on-error、continue-on-error字段。

1
2
3
4
5
6
7
8
name: 步骤名称
env: 该步骤所需的环境变量
run: 该步骤运行的命令,如上面的例子:bash输出环境变量
id : 每个步骤的唯一标识符
uses : 使用哪个 action
with : 指定某个 action 可能需要输入的参数
continue-on-error : 设置为 true 允许此步骤失败 job 仍然通过
timeout-minutes : step 的超时分钟数

极简完整示例(入门可用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: say hi

on: [push, pull_request]

jobs:
my-job:
name: My Job Say Hi
runs-on: ubuntu-latest
steps:
- name: Say Hi
env:
START_STR: Hi there! My name is
USER_NAME: Ber
END_STR: Thank you
run: |
echo $START_STR $USER_NAME $END_STR.

当使用workflow时,一些不能公开的密码、token等,可以使用Secrets 进行保存,在项目仓库中settings->Secrets ->new repository secrets

常用实践建议

  • 锁版本: actions/checkout@v4 这类 action 固定大版本,避免破坏性更新。
  • 分环境: 用 workflow_dispatch.inputs/env 区分 staging/prod
  • 缓存: Node/Go 等项目可用官方缓存 action 加速依赖安装。
  • 安全: 密钥放 Settings > Secrets and variables,在 yml 用 ${{ secrets.NAME }}
  • 并发控制: 用 concurrency 防止重复跑部署。
  • 条件执行: if: 过滤分支、标签、事件类型。

使用场景:部署到另一个仓库(源码仓库 & Pages 仓库分离)

很多人会把 源码仓库Pages 静态站点仓库 分开(例如:
healerape/ohnii-hexo-blog 负责写文章,
healerape/ohnii-hexo-blog-pages 专门存放生成后的 public/)。

这种模式的关键点在于:Actions 默认的 GITHUB_TOKEN 通常只对“当前仓库”有效;你要 push 到另一个仓库,推荐用 PAT(Personal Access Token)(或 SSH Deploy Key)。

使用步骤(推荐):PAT + 仓库 Secret

1)生成 PAT(Classic PAT 示例)

在 GitHub:头像 → SettingsDeveloper settingsPersonal access tokensTokens (classic)

  • 勾选权限:
    • repo(推送代码必须)
    • (可选)workflow(只有当你需要让 token 能修改 workflow 文件时才需要)
  • 生成后会得到一串 token(只显示一次,记得复制保存)。

2)把 PAT 放到源码仓库的 Secret

在源码仓库 ohnii-hexo-blog
SettingsSecrets and variablesActionsNew repository secret

  • Name:GH_TOKEN
  • Value:粘贴刚才生成的 PAT

重点:PAT 和 Secret 的值必须对应同一个 token。如果你在 PAT 页面点了 Regenerate token(或删除重建),旧 token 会立刻失效;此时必须同步更新仓库里的 GH_TOKEN secret 为新 token。

3)workflow 里用 token 推送(两种写法等价)

下面是一个可工作的核心片段(把 public/ 初始化成临时 git 仓库并强推到目标仓库的 gh-pages 分支):

1
2
3
4
5
6
7
8
9
10
11
12
13
- name: Deploy to GitHub Pages (push to another repo)
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
cd public/
git init
git add -A
git commit -m "Deploy from GitHub Actions"
# 写法1(推荐,更明确):x-access-token 前缀
git remote add origin https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/healerape/ohnii-hexo-blog-pages.git
# 写法2(也可用):直接把 token 放在用户名位置
# git remote add origin https://${{ secrets.GH_TOKEN }}@github.com/healerape/ohnii-hexo-blog-pages.git
git push origin HEAD:gh-pages -f

注意点(非常关键)

  • 两个值要对应(务必写清)
    • workflow 里读取的是 ${{ secrets.GH_TOKEN }}
    • 仓库 Secrets 里 GH_TOKEN 的 Value 必须粘贴“当前有效的 PAT 字符串”
    • PAT 一旦 Regenerate/删除重建,必须同步更新 Secrets(否则会认证失败)
  • 目标仓库写权限
    • PAT 属于哪个账号,就要确保该账号对目标仓库 ohnii-hexo-blog-pages 有写权限(Owner/Write)
  • 为什么不用 GITHUB_TOKEN
    • GITHUB_TOKEN 是 Actions 自动注入的,不需要你配置;但它通常只对当前仓库有权限
    • 要跨仓库 push,用 PAT/Deploy Key 更稳
  • 安全建议
    • PAT 尽量设置过期时间(避免长期泄露风险)
    • 能用 Fine-grained token 时,建议只授权“目标仓库 + Contents: Read and write”