GitHub Actions 完整入门教程
目录
什么是 GitHub Actions
GitHub Actions 是 GitHub 提供的持续集成和持续部署(CI/CD)平台,允许你自动化构建、测试和部署流程。你可以在代码仓库中设置工作流,在特定事件发生时自动执行任务。
主要优势
- 与 GitHub 深度集成,无需第三方服务
- 免费额度充足(公共仓库无限制,私有仓库每月 2000 分钟)
- 丰富的社区 Actions 可直接使用
- 支持多种操作系统(Linux、Windows、macOS)
核心概念
Workflow (工作流)
自动化流程的配置文件,存储在 .github/workflows/ 目录下,使用 YAML 格式编写。
Event (事件)
触发工作流运行的特定活动,如 push、pull request、定时任务等。
Job (作业)
工作流中的一组步骤,在同一个运行器上执行。多个作业可以并行或顺序执行。
Step (步骤)
作业中的单个任务,可以运行命令或使用 Action。
Action (动作)
可重用的命令单元,是 GitHub Actions 的最小执行单位。
Runner (运行器)
执行工作流的服务器,GitHub 提供托管运行器,也可以自托管。
第一个工作流
创建工作流文件
在你的 GitHub 仓库中创建文件: .github/workflows/hello.yml
name: Hello World
on: [push]
jobs:
hello-job:
runs-on: ubuntu-latest
steps:
- name: 打印问候语
run: echo "Hello, GitHub Actions!"
- name: 显示当前时间
run: date
工作流说明
name: 工作流的名称,会显示在 GitHub Actions 页面on: 触发事件,这里是任何 push 操作jobs: 定义一个或多个作业runs-on: 指定运行器操作系统steps: 作业中的步骤列表run: 执行 shell 命令
提交这个文件后,每次 push 代码都会自动触发工作流。
工作流语法详解
完整示例
name: CI Workflow
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
NODE_VERSION: '18'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: npm ci
- name: 运行测试
run: npm test
关键语法说明
检出代码
- uses: actions/checkout@v4
这是最常用的 Action,用于检出仓库代码到运行器。
使用环境变量
env:
MY_VAR: 'value'
steps:
- run: echo ${{ env.MY_VAR }}
条件执行
- name: 仅在主分支执行
if: github.ref == 'refs/heads/main'
run: echo "This is main branch"
矩阵策略(多版本测试)
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16, 18, 20]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
常用触发事件
Push 事件
on:
push:
branches:
- main
- 'releases/**' # 通配符匹配
paths:
- '**.js' # 仅当 JS 文件变化时触发
Pull Request 事件
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [ main ]
定时触发(Cron)
on:
schedule:
- cron: '0 0 * * *' # 每天午夜执行
手动触发
on:
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
多事件组合
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 2 * * 1' # 每周一凌晨2点
实战案例
案例1: Node.js 项目 CI/CD
name: Node.js CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v4
- name: 使用 Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: 安装依赖
run: npm ci
- name: 运行 Lint
run: npm run lint
- name: 运行测试
run: npm test
- name: 构建项目
run: npm run build
- name: 上传构建产物
uses: actions/upload-artifact@v4
with:
name: build-files
path: dist/
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: 下载构建产物
uses: actions/download-artifact@v4
with:
name: build-files
- name: 部署到服务器
run: echo "部署逻辑..."
案例2: Python 项目测试
name: Python CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v4
- name: 设置 Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: 安装依赖
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov
- name: 运行测试
run: pytest --cov=./ --cov-report=xml
- name: 上传覆盖率报告
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
案例3: Docker 镜像构建和推送
name: Docker Build and Push
on:
push:
branches: [ main ]
tags: [ 'v*' ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v3
- name: 登录 Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: 提取元数据
id: meta
uses: docker/metadata-action@v5
with:
images: myusername/myapp
- name: 构建并推送
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
进阶技巧
使用 Secrets 保护敏感信息
在仓库设置中添加 Secrets,然后在工作流中使用:
steps:
- name: 部署
env:
API_KEY: ${{ secrets.API_KEY }}
run: ./deploy.sh
作业依赖关系
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building..."
test:
needs: build # 等待 build 完成
runs-on: ubuntu-latest
steps:
- run: echo "Testing..."
deploy:
needs: [build, test] # 等待多个作业
runs-on: ubuntu-latest
steps:
- run: echo "Deploying..."
缓存依赖项
- name: 缓存 Node.js 模块
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
输出变量在步骤间传递
steps:
- name: 设置输出
id: step1
run: echo "version=1.0.0" >> $GITHUB_OUTPUT
- name: 使用输出
run: echo "Version is ${{ steps.step1.outputs.version }}"
并行和串行执行
jobs:
# 这些作业会并行执行
job1:
runs-on: ubuntu-latest
steps:
- run: echo "Job 1"
job2:
runs-on: ubuntu-latest
steps:
- run: echo "Job 2"
# 这个作业等待 job1 和 job2 完成
job3:
needs: [job1, job2]
runs-on: ubuntu-latest
steps:
- run: echo "Job 3"
自定义 Action
创建可重用的 Action(action.yml):
name: 'My Custom Action'
description: '自定义 Action 示例'
inputs:
name:
description: '名字'
required: true
runs:
using: 'composite'
steps:
- run: echo "Hello ${{ inputs.name }}"
shell: bash
使用方式:
steps:
- uses: ./.github/actions/my-action
with:
name: 'World'
调试技巧
启用调试日志
在仓库 Secrets 中添加: ACTIONS_STEP_DEBUG = true
使用 tmate 进行远程调试
- name: 设置 tmate 会话
uses: mxschmitt/action-tmate@v3
查看上下文信息
- name: 打印 GitHub 上下文
run: echo '${{ toJSON(github) }}'
常用资源
最佳实践
- 最小权限原则: 只授予必要的权限
- 使用固定版本: Action 使用完整的版本号或 SHA,如
actions/checkout@v4 - 避免硬编码: 使用环境变量和 Secrets
- 合理使用缓存: 加速构建,但注意缓存失效策略
- 矩阵测试: 在多个版本/环境下测试
- 作业分离: 将构建、测试、部署分成独立作业
- 及时清理: 设置 artifact 保留时间
- 监控配额: 注意免费分钟数使用情况
下一步
学完本教程后,你可以:
- 为现有项目添加 CI/CD 流程
- 探索 GitHub Marketplace 中的 Actions
- 创建自己的可重用 Action
- 学习更高级的工作流模式(如 GitOps、多环境部署)