前端工程化:Github Action 实现 CI/CD

面试导航 是一个专注于前、后端技术学习和面试准备的 免费 学习平台,提供系统化的技术栈学习,深入讲解每个知识点的核心原理,帮助开发者构建全面的技术体系。平台还收录了大量真实的校招与社招面经,帮助你快速掌握面试技巧,提升求职竞争力。如果你想加入我们的交流群,欢迎通过微信联系:yunmz777

GitHub Actions 是 GitHub 提供的持续集成和持续部署(CI/CD)平台,允许开发者自动化软件开发工作流程。通过简单的配置,可实现代码的自动构建、测试和部署,无需额外的服务器或复杂基础设施。

1. GitHub Actions 核心概念

1.1 工作流程 (Workflow)

工作流程是由一系列作业组成的自动化过程,通过在仓库的 .github/workflows 目录下创建 YAML 文件来定义。

yaml 复制代码
name: CI Pipeline
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

1.2 事件 (Event)

事件是触发工作流程的活动,常见的包括:

  • 代码推送 (push)
  • 拉取请求 (pull_request)
  • 定时计划 (schedule)
  • 手动触发 (workflow_dispatch)
  • 外部触发 (repository_dispatch)
yaml 复制代码
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  schedule:
    - cron: "0 0 * * *" # 每天午夜运行

1.3 作业 (Job)

作业是工作流程的执行单元,由一系列步骤组成。默认情况下,多个作业并行执行,但可配置依赖关系实现顺序执行。

yaml 复制代码
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      # 测试步骤

  build:
    needs: test # 依赖于test作业完成
    runs-on: ubuntu-latest
    steps:
      # 构建步骤

1.4 运行器 (Runner)

运行器是执行工作流程的服务器环境。GitHub 提供多种托管环境:

  • Ubuntu Linux
  • Windows
  • macOS

也支持自托管运行器,用于特殊需求场景。

yaml 复制代码
jobs:
  build:
    runs-on: ubuntu-latest # 使用GitHub托管的Ubuntu运行器

1.5 步骤 (Step)

步骤是作业中的最小执行单元,可以是命令或操作。

yaml 复制代码
steps:
  - name: Install dependencies
    run: npm install

  - name: Run tests
    run: npm test

1.6 操作 (Action)

操作是工作流程的可重用构建块,可以是:

  • 公共仓库中的预构建操作
  • 本地仓库中的自定义操作
  • Docker 容器操作
  • JavaScript 操作
yaml 复制代码
steps:
  - name: Checkout code
    uses: actions/checkout@v3

  - name: Setup Node.js
    uses: actions/setup-node@v3
    with:
      node-version: "16"

2. 工作流程配置实践

2.1 基本工作流程结构

yaml 复制代码
name: Node.js CI # 工作流程名称

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

jobs: # 作业定义
  build:
    runs-on: ubuntu-latest

    strategy: # 矩阵策略
      matrix:
        node-version: [14.x, 16.x, 18.x]

    steps: # 步骤定义
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"
      - run: npm ci
      - run: npm test

2.2 环境变量与敏感信息

环境变量可在工作流程、作业或步骤级别定义:

yaml 复制代码
jobs:
  build:
    runs-on: ubuntu-latest
    env: # 作业级环境变量
      NODE_ENV: production
      API_KEY: ${{ secrets.API_KEY }} # 使用仓库密钥

    steps:
      - name: Use environment variables
        run: echo $NODE_ENV

      - name: Deploy with sensitive data
        env: # 步骤级环境变量
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
        run: ./deploy.sh

2.3 矩阵构建与并行测试

矩阵策略允许在多种配置下并行测试代码:

yaml 复制代码
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [14.x, 16.x, 18.x]
        # 可选:排除特定组合
        exclude:
          - os: windows-latest
            node-version: 14.x

    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm test

2.4 依赖缓存优化

缓存可显著加速工作流程执行:

yaml 复制代码
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

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

      - name: Install Dependencies
        run: npm install

3. 实用工作流程示例

3.1 前端应用部署到 GitHub Pages

yaml 复制代码
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "16"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

3.2 Node.js 包发布到 npm

yaml 复制代码
name: Publish to npm

on:
  release:
    types: [created]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: "16"
          cache: "npm"
      - run: npm ci
      - run: npm test

  publish:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: "16"
          registry-url: "https://registry.npmjs.org"
      - run: npm ci
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

3.3 Docker 镜像构建与推送

yaml 复制代码
name: Docker CI/CD

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

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to DockerHub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: username/app-name
          tags: |
            type=semver,pattern={{version}}
            type=ref,event=branch

      - name: Build and push
        uses: docker/build-push-action@v3
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

4. 高级功能与最佳实践

4.1 作业间数据共享

使用工件 (Artifacts) 可在不同作业之间传递数据:

yaml 复制代码
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build
        run: npm run build
      - name: Upload build artifact
        uses: actions/upload-artifact@v3
        with:
          name: build-files
          path: dist/
          retention-days: 1 # 设置保留期限

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v3
        with:
          name: build-files
          path: dist/
      - name: Deploy
        run: ./deploy.sh

4.2 条件执行与环境分支

使用条件表达式控制工作流程执行流程:

yaml 复制代码
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm test

  deploy-staging:
    needs: test
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to staging
        run: ./deploy-staging.sh

  deploy-production:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to production
        run: ./deploy-production.sh

4.3 可重用工作流程

将常用配置提取为可重用工作流程:

yaml 复制代码
# .github/workflows/reusable-build.yml
name: Reusable build workflow

on:
  workflow_call:
    inputs:
      node-version:
        required: false
        default: "16"
        type: string

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci
      - run: npm run build

在其他工作流程中调用:

yaml 复制代码
# .github/workflows/main.yml
name: Main workflow

on: [push]

jobs:
  call-build:
    uses: ./.github/workflows/reusable-build.yml
    with:
      node-version: "18"

4.4 自定义操作开发

创建自定义 JavaScript 操作:

yaml 复制代码
# action.yml
name: "Hello World"
description: "Greet someone"
inputs:
  who-to-greet:
    description: "Who to greet"
    required: true
    default: "World"
outputs:
  time:
    description: "The time we greeted you"
runs:
  using: "node16"
  main: "index.js"
javascript 复制代码
// index.js
const core = require("@actions/core");

try {
  const nameToGreet = core.getInput("who-to-greet");
  console.log(`Hello ${nameToGreet}!`);
  const time = new Date().toTimeString();
  core.setOutput("time", time);
} catch (error) {
  core.setFailed(error.message);
}

5. 安全与性能优化

5.1 安全最佳实践

  • 使用最小权限原则:限制工作流程的权限范围
yaml 复制代码
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      deployments: write
  • 敏感信息管理:使用仓库密钥和环境密钥存储敏感信息
  • 定期更新操作版本:使用特定版本的操作,并定期更新
  • 代码扫描与依赖分析:使用 CodeQL 和依赖扫描工具

5.2 性能优化技巧

  • 精简工作流程:拆分大型工作流程,避免不必要的步骤
  • 有效使用缓存:缓存依赖、构建产物和测试结果
  • 条件步骤执行 :使用 if 条件控制步骤执行
yaml 复制代码
steps:
  - name: Build only on main branch
    if: github.ref == 'refs/heads/main'
    run: npm run build
  • 并行作业执行:使用矩阵策略并行执行任务
  • 自托管运行器优化:为高负载任务配置高性能自托管运行器

6. GitHub Actions 与其他 CI/CD 工具对比

特性 GitHub Actions Jenkins GitLab CI CircleCI
托管方式 云托管/自托管 自托管 云托管/自托管 云托管
配置语法 YAML Jenkinsfile/UI YAML YAML
代码库集成 原生集成 插件集成 原生集成 需配置
免费计划 公开仓库免费 私有仓库有配额 开源免费 公开仓库免费 私有仓库有配额 有限免费计划
生态系统 GitHub Marketplace 插件中心 GitLab 集成 Orbs
学习曲线 相对平缓 较陡峭 中等 中等

7. 最佳实践与经验总结

  1. 模块化组织工作流程:将功能划分为独立的工作流程文件,提高可维护性

  2. 版本化引用外部操作:总是使用具体版本号而非分支名

yaml 复制代码
# 推荐
uses: actions/checkout@v3

# 不推荐
uses: actions/checkout@main
  1. 明确的命名规范:为工作流程、作业和步骤使用清晰描述性的名称

  2. 充分利用内置功能:使用矩阵策略、条件执行和缓存等内置功能

  3. 自动化监控:设置工作流程失败通知和性能监控

  4. 文档化与知识共享:为自定义操作和工作流程撰写清晰文档

  5. 定期审查与优化:随着项目发展,定期评估和改进工作流程

结语

GitHub Actions 提供了强大而灵活的自动化能力,能够满足从简单的个人项目到复杂的企业应用的各种需求。通过本指南介绍的概念和最佳实践,你可以构建高效、可靠的 CI/CD 流水线,提升开发效率,保障代码质量。

无论你是初次接触自动化工作流程,还是寻求优化现有流程,GitHub Actions 都能为你提供简洁而强大的解决方案。开始尝试这些配置示例,探索更多可能性,让你的开发流程更加智能、高效!

相关推荐
想用offer打牌1 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅1 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60612 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX2 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了2 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅2 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法3 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅3 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment3 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端