Skip to content
On this page

GitHub Actions 快速入门

GitHub Actions是GitHub的持续集成和持续部署(CI/CD)平台,允许您自动化构建、测试和部署工作流程。通过GitHub Actions,您可以创建自定义工作流程来响应GitHub事件,如代码推送、拉取请求等。

什么是GitHub Actions

GitHub Actions是一种自动化工具,允许您在GitHub仓库中创建自定义工作流程。工作流程是自动化过程,可以构建、测试、打包、发布或部署任何项目。

核心概念

  • 工作流程(Workflow):自动化过程,包含一个或多个作业
  • 作业(Job):在运行器上执行的一组步骤
  • 步骤(Step):在作业中执行的单个任务
  • 动作(Action):可重用的独立命令,是工作流程中的最小执行单元
  • 事件(Event):触发工作流程运行的特定活动

基本工作流文件结构

GitHub Actions工作流定义在YAML文件中,存储在仓库的.github/workflows/目录下:

yaml
# .github/workflows/ci.yml
name: CI # 工作流名称

on: [push, pull_request] # 触发事件

jobs: # 作业定义
  build: # 作业名称
    runs-on: ubuntu-latest # 运行环境
    
    steps: # 步骤列表
    - name: Checkout code
      uses: actions/checkout@v4 # 使用预定义动作
      
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '18'
        
    - name: Install dependencies
      run: npm install
      
    - name: Run tests
      run: npm test

创建第一个工作流

1. 创建工作流目录

在您的仓库根目录下创建以下目录结构:

.github/
└── workflows/
    └── ci.yml

2. 基本工作流示例

yaml
name: Node.js CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x, 18.x, 20.x]

    steps:
    - uses: actions/checkout@v4
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
        
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test

触发工作流

基本触发方式

yaml
# 在push和pull_request事件时触发
on: [push, pull_request]

# 或者使用详细语法
on:
  push:
    branches: [ main, develop ]
    paths: 
      - 'src/**'
      - 'package.json'
  pull_request:
    branches: [ main ]
    types: [opened, synchronize, reopened]

高级触发方式

yaml
on:
  # 定时触发(cron语法)
  schedule:
    - cron: '0 2 * * 1' # 每周一凌晨2点
    
  # 手动触发
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'     
        required: true
        default: 'warning'
      tags:
        description: 'Test scenario tags'  
        
  # 仓库调度
  repository_dispatch:
    types: [webhook-payload]

常用预定义动作

代码检出

yaml
- name: Checkout repository
  uses: actions/checkout@v4
  with:
    fetch-depth: 0  # 获取所有历史记录

设置Node.js环境

yaml
- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: '18'
    cache: 'npm'  # 启用依赖缓存

设置Python环境

yaml
- name: Setup Python
  uses: actions/setup-python@v4
  with:
    python-version: '3.11'
    cache: 'pip'  # 启用pip缓存

设置Java环境

yaml
- name: Setup Java
  uses: actions/setup-java@v4
  with:
    distribution: 'temurin'
    java-version: '17'
    cache: 'maven'

环境变量和密钥

设置环境变量

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      NODE_ENV: production
      API_URL: https://api.example.com
    steps:
      - name: Use environment variable
        run: echo $NODE_ENV

使用密钥

yaml
- name: Deploy to production
  run: deploy-script.sh
  env:
    API_KEY: ${{ secrets.API_KEY }}
    DATABASE_URL: ${{ secrets.DATABASE_URL }}

条件执行

基本条件

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Run on main branch
        if: github.ref == 'refs/heads/main'
        run: echo "Running on main branch"
        
      - name: Run on feature branches
        if: startsWith(github.ref, 'refs/heads/feature/')
        run: echo "Running on feature branch"

高级条件

yaml
- name: Conditional step
  if: github.event_name == 'push' && contains(github.ref, 'main')
  run: echo "Push event on main branch"

矩阵构建

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [16.x, 18.x, 20.x]
      fail-fast: false  # 即使一个矩阵作业失败也继续其他作业
    
    steps:
    - uses: actions/checkout@v4
    - name: Setup Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - run: npm test

实际应用示例

Node.js项目完整CI/CD

yaml
name: Node.js CI/CD

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

env:
  NODE_VERSION: '18.x'

jobs:
  lint-and-test:
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'
        
    - name: Install dependencies
      run: npm ci
      
    - name: Lint code
      run: npm run lint
      
    - name: Run tests
      run: npm test -- --coverage
      env:
        CI: true
        
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3

  build:
    needs: lint-and-test  # 依赖于前面的作业
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'
    - run: npm ci
    - run: npm run build
    
    - name: Upload build artifacts
      uses: actions/upload-artifact@v3
      with:
        name: build-files
        path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'  # 仅在main分支运行
    
    steps:
    - name: Download build artifacts
      uses: actions/download-artifact@v3
      with:
        name: build-files
        path: dist/
        
    - name: Deploy to production
      run: |
        # 部署脚本
        echo "Deploying to production..."

虚拟环境

GitHub Actions提供以下虚拟环境:

  • Ubuntu:ubuntu-latest, ubuntu-22.04, ubuntu-20.04
  • Windows:windows-latest, windows-2022, windows-2019
  • macOS:macos-latest, macos-12, macos-11
yaml
jobs:
  cross-platform-test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - run: echo "Running on ${{ runner.os }}"

缓存依赖

yaml
- name: Cache node modules
  id: cache-npm
  uses: actions/cache@v3
  with:
    path: node_modules
    key: ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-npm-cache-

- name: Install dependencies
  if: steps.cache-npm.outputs.cache-hit != 'true'
  run: npm ci

工作流命令

在工作流中可以使用特殊命令:

yaml
- name: Set output
  run: |
    echo "time=$(date)" >> $GITHUB_OUTPUT
    
- name: Set environment variable for next steps
  run: echo "BUILD_VERSION=1.0.0" >> $GITHUB_ENV

- name: Add problem matcher
  run: echo "::add-matcher::.github/problem-matcher.json"

调试工作流

启用调试日志

在仓库的Secrets中添加:

  • ACTIONS_STEP_DEBUG = true (启用步骤调试)
  • ACTIONS_RUNNER_DEBUG = true (启用运行器调试)

常用调试步骤

yaml
- name: Debug environment
  run: |
    echo "Event name: ${{ github.event_name }}"
    echo "Ref: ${{ github.ref }}"
    echo "Actor: ${{ github.actor }}"
    env:
      GITHUB_CONTEXT: ${{ toJson(github) }}

总结

GitHub Actions提供了一个强大的自动化平台,可以满足各种CI/CD需求。通过合理配置工作流程,您可以实现从代码提交到部署的全自动化流程。在接下来的章节中,我们将深入探讨GitHub Actions的各个高级特性和最佳实践。