你还在手动部署代码?
每次代码上线,步骤是不是这样:
- 本地写代码
- 推送到 Git
- SSH 到服务器
- git pull
- 重启服务
- 检查日志
如果团队有3个人,还得先合并代码、解决冲突、逐个测试。繁琐还容易出错。
GitHub Actions 可以帮你自动化这一切。
它不需要买额外的 CI/CD 服务,也不需要维护 Jenkins 服务器。代码推到 GitHub,流水线自动跑。
下面从基础到实战,一步步教你配置。
一、Workflow 是什么?
Workflow(工作流)是 GitHub Actions 的基本单位。一个 Workflow 就是一个 YAML 文件,定义"什么时候做什么"。
文件放在仓库的 .github/workflows/ 目录里。
my-project/
├── .github/
│ └── workflows/
│ └── ci.yml # CI 工作流
│ └── deploy.yml # 部署工作流
├── src/
└── README.md
二、最简 CI 流水线
先写一个最简单的:代码推送时自动跑测试。
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置 Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: 安装依赖
run: pip install -r requirements.txt
- name: 运行测试
run: pytest tests/
解读:
name: 工作流名称,显示在 GitHub Actions 页面on: 触发条件。这里配置了 push 和 pull_request 到 main 分支时触发jobs: 定义任务。这里只有一个test任务runs-on: 运行环境。ubuntu-latest是 GitHub 提供的云服务器steps: 任务步骤。每步可以是 GitHub 官方 Action 或自定义命令
三、多阶段流水线:测试 → 构建 → 部署
实际项目通常需要多阶段。下面是一个完整例子:
name: Build and Deploy
on:
push:
branches: [main]
jobs:
# 阶段1:测试
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install -r requirements.txt
- run: pytest tests/
- name: 上传测试报告
uses: actions/upload-artifact@v4
with:
name: test-report
path: coverage/report.html
# 阶段2:构建(依赖测试通过)
build:
needs: test # 等 test job 完成
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 构建 Docker 镜像
run: docker build -t myapp:${{ github.sha }} .
- name: 推送镜像到 GitHub Container Registry
run: |
echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker push ghcr.io/${{ github.repository }}:latest
# 阶段3:部署(依赖构建成功)
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # 只在 main 分支部署
steps:
- uses: actions/checkout@v4
- name: 部署到服务器
run: |
ssh deploy@myserver.com "docker pull ghcr.io/${{ github.repository }}:latest"
ssh deploy@myserver.com "docker compose up -d"
关键点:
needs: 定义 job 依赖关系。build等test完成,deploy等build完成if: 条件判断。只有 main 分支才部署${{ github.sha }}: GitHub 内置变量,表示当前 commit hashsecrets: 敏感信息(如 SSH 密钥、密码)存在 GitHub Secrets 里,用${{ secrets.NAME }}引用
四、常用触发条件
on:
# 代码推送时
push:
branches: [main, develop]
tags: ['v*']
# PR 时
pull_request:
branches: [main]
# 定时触发(每天凌晨2点)
schedule:
- cron: '0 2 * * *'
# 手动触发(GitHub UI 点击)
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
# 监听其他仓库事件
repository_dispatch:
types: [deploy-hook]
# 监听 issue 事件
issues:
types: [opened, labeled]
cron 格式:分 时 日 月 周(5位)。0 2 * * * 表示每天凌晨2点。
五、缓存加速:别让每次构建都从头来
Python 项目安装依赖是最耗时的步骤。用 actions/cache 缓存依赖:
- name: 缓存 pip 依赖
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: 安装依赖
run: pip install -r requirements.txt
原理:第一次构建时下载依赖并缓存。后续构建如果发现 requirements.txt 没变,直接读缓存,跳过下载。
构建时间可以从5分钟缩短到30秒。
六、环境变量和 secrets
环境变量
env:
NODE_ENV: production
DATABASE_URL: ${{ secrets.DB_URL }}
jobs:
build:
runs-on: ubuntu-latest
env:
API_KEY: ${{ secrets.API_KEY }}
steps:
- run: echo "Deploying to $NODE_ENV"
Secrets 管理
在 GitHub 仓库页面:Settings → Secrets and variables → Actions → New repository secret
API_KEY=sk-xxxxxxxx
DB_PASSWORD=xxxxxxxx
GHCR_TOKEN=ghp_xxxxxxxxx
代码里用 ${{ secrets.NAME }} 引用。永远不要把密码写在 YAML 文件里。
七、矩阵构建:一个 job 跑多个环境
测试需要在多个 Python 版本上运行?用矩阵:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pip install -r requirements.txt
- run: pytest tests/
GitHub 会自动创建4个并行的 job,每个用不同 Python 版本运行测试。
还可以加更多维度:
matrix:
python-version: ['3.9', '3.11']
os: [ubuntu-latest, windows-latest]
这会生成 2×2=4 个 job:(3.9+ubuntu, 3.9+windows, 3.11+ubuntu, 3.11+windows)
八、实战:Hugo 站点自动部署
回到 navbox.com.cn 的场景。项目用 Hugo 静态生成,每次更新内容需要重新构建和部署。
# .github/workflows/deploy.yml
name: Deploy Hugo Site
on:
push:
branches: [main]
paths:
- 'content/**'
- 'themes/**'
- 'hugo.toml'
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
with:
submodules: true
- name: 安装 Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.124.0'
- name: 构建站点
run: hugo --gc --minify
- name: 部署到服务器
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "public/"
target: "/var/www/navbox"
- name: 重启服务
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/navbox
nginx -t && nginx -s reload
这个 Workflow 的作用:
- 监控
content/、themes/、hugo.toml的变更 - 用 Hugo 构建静态站点
- 通过 SSH 把
public/同步到服务器 - 重启 Nginx 使新内容生效
九、常见问题排查
问题1:Workflow 挂了但不知道哪里出错
点击 GitHub Actions 页面的具体 job → 展开 step → 看红色错误日志。大部分错误都在日志里。
问题2:runner 资源不足
GitHub 免费账户的 runner 资源有限。大构建任务容易 OOM。
解决:用 runs-on: ubuntu-latest-8cores 或升级到 GitHub Pro。
问题3:敏感信息泄露
永远不要把密码、密钥写在 Workflow YAML 里。用 Secrets。
检查方法:在 GitHub Actions 页面,点击具体 run → 查看 step 日志,看是否打印了敏感内容。
十、总结
GitHub Actions 的精髓就三句话:
- YAML 配置触发条件 — 什么时候跑
- 定义 Job 和步骤 — 跑什么
- 利用缓存和矩阵 — 跑得快
从今天的例子出发,你的项目最适合加哪条自动化流水线?是从 PR 自动跑测试,还是提交代码自动部署?先从小处开始,逐步完善。