免费的 CI/CD 服务,了解一下 GitHub Actions ?

前言

最近做了一个 apk,每次更新都要手动进行打包,再把 apk 分发出去,麻烦!

上网冲浪的时候,发现了这个 android_builder,发现 GitHub Actions 还是很香的,了解一下。

什么是 GitHub Actions

GitHub Actions 是 GitHub 推出的持续集成(CI/CD)服务,于 2018 年 10 月推出。它允许开发者在 GitHub 仓库中直接自动化软件开发工作流程。

核心概念:

  • Workflow(工作流):自动化流程,由一个或多个 Job 组成
  • Job(任务):一组在同一运行器上执行的步骤(Step)
  • Step(步骤):单个任务,可以运行命令或使用 Action
  • Action(动作):可复用的工作流代码单元,是最小的可移植构建块
  • Runner(运行器):执行工作流的服务器,GitHub 提供托管运行器(Ubuntu、Windows、macOS)

主要优势:

  • 🚀 与 GitHub 深度集成,无需第三方 CI/CD 工具
  • 💰 对公开仓库免费,私有仓库每月有免费额度
  • 🔧 丰富的预构建 Actions 可直接使用
  • 🌐 支持多种操作系统和编程语言
  • 📦 社区驱动,有大量开源 Actions 可用

基础语法

GitHub Actions 使用 YAML 格式配置文件,存放在仓库的 .github/workflows/ 目录下。

基本结构

yaml 复制代码
name: 工作流名称

# 触发条件
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

# 任务列表
jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - name: 检出代码
      uses: actions/checkout@v3
      
    - name: 运行命令
      run: echo "Hello, GitHub Actions!"

触发器(Triggers)

1. Push 事件

yaml 复制代码
on:
  push:
    branches:
      - main
      - 'releases/**'
    paths:
      - '**.js'

2. Pull Request 事件

yaml 复制代码
on:
  pull_request:
    types: [opened, synchronize, reopened]

3. 定时触发(Cron)

yaml 复制代码
on:
  schedule:
    - cron: '0 0 * * *'  # 每天午夜运行

4. 手动触发

yaml 复制代码
on:
  workflow_dispatch:
    inputs:
      environment:
        description: '部署环境'
        required: true
        default: 'staging'

5. 多个事件组合

yaml 复制代码
on: [push, pull_request, workflow_dispatch]

常用配置项

环境变量

yaml 复制代码
env:
  NODE_VERSION: '18'
  
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
    steps:
      - run: echo $NODE_VERSION

矩阵策略(Matrix)

yaml 复制代码
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [14, 16, 18]
    steps:
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

条件执行

yaml 复制代码
steps:
  - name: 仅在主分支运行
    if: github.ref == 'refs/heads/main'
    run: echo "这是主分支"

依赖关系

yaml 复制代码
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: npm run build
      
  deploy:
    needs: build  # 等待 build 完成
    runs-on: ubuntu-latest
    steps:
      - run: npm run deploy

实际应用示例

1. 前端项目 CI/CD

场景: React 项目的自动化测试、构建和部署

yaml 复制代码
name: Frontend CI/CD

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

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: 设置 Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        cache: 'npm'
    
    - name: 安装依赖
      run: npm ci
    
    - name: 代码检查
      run: npm run lint
    
    - name: 运行测试
      run: npm test
    
    - name: 构建项目
      run: npm run build
    
    - name: 部署到 GitHub Pages
      if: github.ref == 'refs/heads/main'
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./build

2. 后端测试

场景: Go 语言项目的自动化测试和代码覆盖率

yaml 复制代码
name: Go API Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:14
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    
    steps:
    - uses: actions/checkout@v3
    
    - name: 设置 Go 环境
      uses: actions/setup-go@v4
      with:
        go-version: '1.21'
    
    - name: 下载依赖
      run: go mod download
    
    - name: 运行测试
      run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
    
    - name: 上传代码覆盖率
      uses: codecov/codecov-action@v3
      with:
        files: ./coverage.txt

3. 自动发布版本

场景: 创建 Tag 时自动发布 Release

yaml 复制代码
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: 构建二进制文件
      run: |
        GOOS=linux GOARCH=amd64 go build -o app-linux-amd64
        GOOS=windows GOARCH=amd64 go build -o app-windows-amd64.exe
        GOOS=darwin GOARCH=amd64 go build -o app-darwin-amd64
    
    - name: 创建 Release
      uses: softprops/action-gh-release@v1
      with:
        files: |
          app-linux-amd64
          app-windows-amd64.exe
          app-darwin-amd64
        body: |
          ## 更新内容
          - 功能改进
          - Bug 修复
        draft: false
        prerelease: false
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4. 定时任务

场景: 每天自动爬取数据并提交

yaml 复制代码
name: Daily Data Sync

on:
  schedule:
    - cron: '0 2 * * *'  # 每天凌晨 2 点
  workflow_dispatch:  # 支持手动触发

jobs:
  sync:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: 设置 Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    
    - name: 安装依赖
      run: pip install -r requirements.txt
    
    - name: 运行爬虫
      run: python scraper.py
    
    - name: 提交更改
      run: |
        git config --local user.email "action@github.com"
        git config --local user.name "GitHub Action"
        git add data/
        git diff --quiet && git diff --staged --quiet || (git commit -m "chore: update data [skip ci]" && git push)

5. Docker 镜像构建与发布

场景: 自动构建并推送 Docker 镜像到 Docker Hub

yaml 复制代码
name: Docker Build and Push

on:
  push:
    branches: [ main ]
    tags: [ 'v*' ]

jobs:
  docker:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: 设置 Docker Buildx
      uses: docker/setup-buildx-action@v2
    
    - name: 登录 Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}
    
    - name: 提取元数据
      id: meta
      uses: docker/metadata-action@v4
      with:
        images: myusername/myapp
    
    - name: 构建并推送
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

6. 代码质量检查

场景: 自动进行代码审查和安全扫描

yaml 复制代码
name: Code Quality

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: 运行 ESLint
      uses: reviewdog/action-eslint@v1
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        reporter: github-pr-review
    
  security:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: 运行安全扫描
      uses: aquasecurity/trivy-action@master
      with:
        scan-type: 'fs'
        scan-ref: '.'
        format: 'sarif'
        output: 'trivy-results.sarif'
    
    - name: 上传扫描结果
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: 'trivy-results.sarif'

运行机制

工作原理

  1. 事件触发:当仓库中发生特定事件(push、PR、issue 等)时,GitHub 会检查是否有对应的工作流配置

  2. Runner 分配:GitHub 从 Runner 池中分配一个可用的运行器(或使用自托管 Runner)

  3. 环境准备

    • 创建虚拟环境(VM 或容器)
    • 克隆仓库代码
    • 设置环境变量
  4. 执行步骤

    • 按顺序执行每个 Step
    • 每个 Step 可以是 Shell 命令或 Action
    • Step 之间共享文件系统但不共享环境变量(除非显式传递)
  5. 结果报告

    • 收集执行日志
    • 报告成功/失败状态
    • 可选:发送通知、创建 Check Run

Action 复用机制

Action 可以通过三种方式引用:

  1. 公共仓库uses: actions/checkout@v3
  2. 私有仓库uses: owner/repo@ref
  3. 本地路径uses: ./.github/actions/my-action

Action 本质是:

  • JavaScript Action:Node.js 脚本
  • Docker Action:Docker 容器
  • Composite Action:组合多个步骤

Secrets 管理

GitHub Actions 使用加密存储来保护敏感信息:

  • Secrets 在传输和存储时都经过加密
  • 日志输出会自动屏蔽 Secrets 内容
  • Secrets 仅对有权限的工作流可见
  • 支持仓库级、组织级和环境级 Secrets

并发与限制

并发限制:

  • 公共仓库:20 个并发任务
  • 私有仓库:根据计费方案不同(5-180 个)

使用限制:

  • 每个工作流最多运行 72 小时
  • 每个 Job 最多 6 小时
  • API 请求限制:1000 次/小时
  • Artifact 存储:90 天自动删除

免费额度(私有仓库):

  • Linux:2000 分钟/月
  • Windows:1000 分钟/月(2 倍计费)
  • macOS:200 分钟/月(10 倍计费)

参考

相关推荐
卓码软件测评2 小时前
K6的CI/CD集成在云原生应用的性能测试应用
前端·功能测试·测试工具·ci/cd·云原生
DeepHacking3 小时前
GitHub代码推送指南
github
破坏的艺术3 小时前
GitHub Spec Kit:官方规格驱动开发工具包深度解析
github·vibe coding
恒雨田5 小时前
Jenkins安装并与GitLab集成,实现dev、qa、uat、prod多分支持续集成的详细步骤
ci/cd·gitlab·jenkins
京东零售技术19 小时前
京东正式开源基于国产芯片自研的xLLM大模型推理引擎
github
寻月隐君20 小时前
Rust 泛型编程基石:AsRef 和 AsMut 的核心作用与实战应用
后端·github
ayyyy____20 小时前
把项目通过pycharm上传到github(两种方式)
ide·pycharm·github
专注VB编程开发20年21 小时前
vb.net编写DDE(Dynamic Data Exchange)服务器
运维·服务器·github·vb.net·dde
qq_3775727721 小时前
github repository 一个文件忘记添加到 .gitignore
github