跳到主要内容

GitHub Actions 完整入门教程

目录

  1. 什么是 GitHub Actions
  2. 核心概念
  3. 第一个工作流
  4. 工作流语法详解
  5. 常用触发事件
  6. 实战案例
  7. 进阶技巧

什么是 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) }}'

常用资源

最佳实践

  1. 最小权限原则: 只授予必要的权限
  2. 使用固定版本: Action 使用完整的版本号或 SHA,如 actions/checkout@v4
  3. 避免硬编码: 使用环境变量和 Secrets
  4. 合理使用缓存: 加速构建,但注意缓存失效策略
  5. 矩阵测试: 在多个版本/环境下测试
  6. 作业分离: 将构建、测试、部署分成独立作业
  7. 及时清理: 设置 artifact 保留时间
  8. 监控配额: 注意免费分钟数使用情况

下一步

学完本教程后,你可以:

  • 为现有项目添加 CI/CD 流程
  • 探索 GitHub Marketplace 中的 Actions
  • 创建自己的可重用 Action
  • 学习更高级的工作流模式(如 GitOps、多环境部署)