使用 GitHub Actions 搭建 CI/CD 流水线:完整配置指南
在现代软件开发中,每次代码变更后手动测试和运行部署脚本已成为拖慢交付速度、引入人为错误的瓶颈。CI/CD 流水线能够自动化整个流程,从代码测试到生产环境部署。本指南将通过实用的 YAML 示例,教你如何使用功能强大且深度集成的自动化平台 GitHub Actions 搭建 CI/CD 流水线,让你更快速、更可靠地交付代码。
你将学到什么
学完本指南后,你将理解持续集成和持续部署(CI/CD)的核心概念,并能够使用 GitHub Actions 实现多阶段流水线。你将学会编写用于自动化测试、构建 Docker 镜像和部署应用的工作流。你将获得可直接用于测试、构建和部署自己项目(无论是 Python、Node.js 还是容器化应用)的 YAML 代码。
理解 GitHub Actions 基础
GitHub Actions 是一个事件驱动的自动化平台,直接集成在 GitHub 仓库中。它允许你运行由 push、pull_request 或 release 等事件触发的自动化工作流。工作流定义在位于 .github/workflows/ 目录下的 YAML 文件中,默认情况下包含一个或多个并行运行的作业,每个作业由一系列步骤组成。
核心组件
- 事件(
on):触发工作流的事件,例如推送到特定分支或创建拉取请求。 - 运行器(
runs-on):执行作业的机器。ubuntu-latest是最常用且推荐的选择,因其性能优越且软件支持广泛。 - 步骤:作业中的单个任务。可以是 shell 脚本(
run)或来自 GitHub Marketplace 的预构建操作(uses)。 - 操作:可复用的代码单元,例如
actions/checkout@v4用于克隆仓库,或actions/setup-node@v4用于安装 Node.js。
入门基础工作流
最简单的做法是让工作流在每次推送时触发。创建 .github/workflows/main.yml 文件,运行一个基本的 "Hello World" 命令。
name: example
on: push
jobs:
greeting:
runs-on: ubuntu-latest
steps:
- run: echo "Hello, CI/CD World!"
将此文件提交并推送到仓库后,你可以在 GitHub 仓库的 "Actions" 标签页中查看作业的输出。
构建全面的 CI 流水线
流水线中的 "CI" 部分确保代码变更在合并前自动通过测试和验证。这通常包括代码检查、类型检查和运行单元测试。
CI 工作流文件
创建 .github/workflows/ci.yml。该工作流会在每次推送到 main 分支或创建针对 main 分支的拉取请求时触发。以下示例展示了 Node.js 项目的完整流水线,但该模式同样适用于其他语言(例如使用 actions/setup-python 的 Python 项目)。
name: CI Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test
build:
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
关键特性说明
- 依赖缓存:
actions/setup-node中的cache: 'npm'选项通过复用之前运行的依赖,显著加快工作流速度。 - 作业依赖:
needs关键字定义了执行顺序。例如,build作业仅在lint和test作业成功后才运行,从而避免浪费时间构建有问题的代码。 - 环境变量:对于数据库等服务,你可以定义环境变量。例如,
test作业可以启动一个 PostgreSQL 服务容器,并使用env连接到它。
高级场景:容器化与多环境部署
对于现代应用,流水线通常涉及构建容器镜像和部署。下表概述了常见的部署策略及其触发器。
部署触发器对比
| 策略 | 部署触发器 | 适用场景 |
|---|---|---|
| 基于分支 | 推送到 main 分支 |
持续部署最新开发代码 |
| 基于标签 | 推送新标签(例如 v1.0.0) |
向生产环境发布稳定的版本化软件 |
| 基于发布 | 在 GitHub 上发布 Release | 官方产品发布,同时生成发布说明 |
示例:使用 CI/CD 工作流部署 Docker 容器
这个综合示例演示了测试 Python 应用、构建 Docker 镜像并将其推送到镜像仓库的流水线。它使用一系列官方 Docker 操作来实现安全、高性能的构建。
创建 .github/workflows/deploy.yml:
name: Complete CI/CD Pipeline
on:
push:
branches: [ main ]
release:
types: [published]
env:
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }}
IMAGE_NAME: my-app
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.9'
- run: pip install -r requirements.txt
- run: pytest
build-and-push:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' || github.event_name == 'release'
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_HUB_USERNAME }}
password: ${{ env.DOCKER_HUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_HUB_USERNAME }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
runs-on: ubuntu-latest
needs: build-and-push
if: github.event_name == 'release'
steps:
- name: Execute Deployment Script
run: |
echo "Deploying image ${{ env.DOCKER_HUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}"
重要提示:密钥管理
要使上述工作流正常运行,你必须将凭据安全地存储在 GitHub 仓库中。导航到 Settings > Secrets and variables > Actions,然后添加以下密钥:
DOCKER_HUB_USERNAME:你的 Docker Hub 用户名。DOCKER_HUB_TOKEN:具有读写权限的 Docker Hub 个人访问令牌。
⚠️ 安全警告:切勿将密码、令牌或其他敏感数据直接硬编码在 YAML 文件中。始终使用 GitHub 密钥,这些密钥经过加密,仅在运行工作流时可访问。
常见问题解答
使用 GitHub Actions 搭建 CI/CD 流水线的第一步是什么?
首先,在仓库中创建 .github/workflows 目录。然后,在该目录下创建一个 YAML 文件(例如 ci.yml),并定义 name、on(触发事件,如 push)和 jobs(要运行的任务)。提交并推送此文件即可启动第一个自动化工作流。
能否使用 GitHub Actions 在拉取请求上运行测试?
可以,在拉取请求上运行测试是核心用例之一。通过将 on 触发器设置为针对 main 分支的 pull_request,工作流会在每个新的拉取请求上自动运行,从而在合并前确保代码质量。
如何使用 GitHub Actions 工作流构建并推送 Docker 镜像?
你可以使用官方组合操作,如 docker/login-action、docker/setup-buildx-action 和 docker/build-push-action。这简化了流程,自动处理身份验证,并支持构建缓存和多平台构建等功能。
能否使用 GitHub Actions 部署到 GitHub Pages?
可以。你可以使用社区操作 JamesIves/github-pages-deploy-action。配置时指定包含已构建站点的文件夹,该操作会自动处理 git 操作,将更改提交并推送到 gh-pages 分支。
push 和 release 事件触发器有什么区别?
push 事件在代码推送到指定分支时触发工作流。release 事件在 GitHub Release 发布时触发。push 通常用于持续集成和预发布环境部署,而 release 通常用于部署到生产环境。
参考来源
- Set up GitHub Actions CI/CD pipeline · Issue #176(包含 CI、端到端测试和部署的实用 YAML 示例)
- DevOps: Set up GitHub Actions CI/CD pipeline · Issue #19(演示代码检查、类型检查和构建验证)
- GitHub - kamrun111/GitHubActionTest(一个简单、适合初学者的 Python CI/CD 示例)
- @jamesives/github-pages-deploy-action(部署到 GitHub Pages 的文档)
- GitHub - CarlosQuintero8/cicdsimulation(演示包含测试、构建和部署到 GitHub Pages 的多阶段流水线)
- GitHub - anuragstark/Py-app-CI-CD-Pipeline-(包含 Docker 和 Minikube 部署的综合指南)
- Automated CI/CD with GitHub Actions, starting from scratch(逐步构建 CI/CD 工作流的教程)
- Extend App with GitHub Actions · AccelByte Documentation(由发布事件触发的部署示例)
- Configure CI/CD for your C++ application · Docker Docs(演示使用 Docker Hub 配置 GitHub Actions)
- Hello CI World · HSF Training(创建和运行第一个工作流的基础教程)
— Editorial Team
暂无评论。