DevOps 四大支柱的第二根:CI/CD(持续集成 / 持续交付)。前几课你学了命令行、Git、脚本、Docker——CI/CD 就是把这些串成一条自动流水线。
从现在起,你 push 代码,GitHub 自动帮你做这些事:
git push ──→ 自动跑 lint ──→ 自动跑测试 ──→ 自动构建 Docker 镜像 ──→ 自动部署
↓ 失败? ↓ 成功?
PR 上直接标红, 合并后自动上线
merge 按钮灰掉
GitHub Actions 是最流行的免费 CI/CD 平台,直接内建在 GitHub 里。它的工作方式:
| 概念 | 是什么 | 类比 |
|---|---|---|
| Workflow(工作流) | 一个 YAML 文件,定义整条流水线 | Shell 脚本的高级版 |
| Job(任务) | 流水线的一个独立执行单元 | 脚本里的一个函数 |
| Step(步骤) | Job 里的一个具体操作 | 函数里的一行命令 |
| Runner(执行器) | 跑 Workflow 的虚拟机(Ubuntu/macOS/Windows) | 临时租的一台云服务器 |
| Action(动作) | 可复用的步骤,社区共享 | npm 包 |
把它放在 .github/workflows/ci.yml,push 到 GitHub 就自动运行。
name: CI # Workflow 的名字(在 GitHub UI 显示)
on: # 什么时候触发
push:
branches: [main] # push 到 main 时
pull_request:
branches: [main] # 向 main 发 PR 时
jobs: # 要跑哪些任务
test: # 任务名(自定义)
runs-on: ubuntu-latest # 在什么系统上跑
steps: # 任务里的步骤
- uses: actions/checkout@v4 # Step 1: 拉代码(官方 Action)
- uses: actions/setup-node@v4 # Step 2: 装 Node.js
with:
node-version: 22
cache: 'npm' # 自动缓存 node_modules
- run: npm ci # Step 3: 装依赖
- run: npm run lint --if-present # Step 4: lint(有的话)
- run: npm test --if-present # Step 5: 跑测试
拆解:
on.push.branches: [main] — push 到 main 就触发。也可以用 on: [push](任何分支 push 都触发)runs-on: ubuntu-latest — GitHub 免费提供一台全新的 Ubuntu VMuses: actions/checkout@v4 — 把仓库代码 checkout 到这台 VM 上。几乎所有 workflow 的第一步uses: actions/setup-node@v4 — 安装指定版本的 Node.js。GitHub 维护了所有主流语言的 setup actionrun: npm ci — 直接跑命令,跟在终端里敲一样加上 Docker 构建和推送(需要先在 GitHub 上设置 Secrets):
name: CI + Docker
on:
push:
branches: [main]
tags: ['v*'] # v1.0.0 这种 tag push 时也触发
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: 'npm' }
- run: npm ci
- run: npm test
docker:
needs: test # 等 test job 通过了才跑这个
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }} # 从 GitHub Secrets 读取
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: myuser/my-app:latest
关键点:
needs: test — test 通过了才跑 docker。失败则 docker job 直接跳过${{ secrets.DOCKER_USERNAME }} — Secrets 存在 GitHub 仓库设置里,workflow 日志中会自动隐藏,不会泄漏tags: ['v*'] — 只有打 v 开头的 tag 时才触发 docker job(更精细的控制方式)on:
push: # 代码 push
pull_request: # 发 PR
schedule:
- cron: '0 2 * * 1' # 每周一凌晨 2 点(UTC)
workflow_dispatch: # 允许手动触发(GitHub UI 上点按钮)
在 GitHub 仓库页面 → Settings → Secrets and variables → Actions → New repository secret。把敏感信息(Docker Hub 密码、SSH 私钥、API token)存在这,workflow 里用 ${{ secrets.NAME }} 读取。
***。但如果你在脚本里 echo $SECRET,它会被隐藏;如果你 echo $SECRET | base64,base64 编码后的值不会被隐藏——所以别把 secret 做任何转换再输出。
目标:为 ~/code/podcast 创建 GitHub Actions workflow。
# 1. 创建 workflow 目录
mkdir -p ~/code/podcast/.github/workflows
# 2. 创建 ci.yml
cat > ~/code/podcast/.github/workflows/ci.yml << 'EOF'
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test --if-present
EOF
# 3. 验证 YAML 语法(可以装个 yamllint)
cat ~/code/podcast/.github/workflows/ci.yml
# 4. (可选)push 到 GitHub 看它跑起来
# cd ~/code/podcast && git add .github && git commit -m "ci: add GitHub Actions" && git push
运行结果:每次 push 到 main,GitHub 会:拉代码 → 装 Node 22 → npm ci → npm run build → npm test。全部通过就在 commit 旁边显示绿色 ✓。
你的 CI/CD 流水线跑起来了。但代码最终要部署到服务器上。下一课——部署实战:从 Docker 镜像到公网可访问,你将在云服务器上把你的容器真正跑起来。
~/code/podcast 推上去试试。没有 GitHub 账户也可以只把 workflow 文件写好,理解结构就行。workflow 的 YAML 本身不依赖 GitHub——GitLab CI、Bitbucket Pipelines 的语法非常相似。