前端工程化: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 都能为你提供简洁而强大的解决方案。开始尝试这些配置示例,探索更多可能性,让你的开发流程更加智能、高效!

相关推荐
Asthenia04125 分钟前
Redis性能与优势/对比其他Key-Value存储/数据类型及底层结构/相同数据结构原因/对比Memcached优势/字符串最大容量/RDB与AOF分析
后端
鱼樱前端12 分钟前
Rollup 在前端工程化中的核心应用解析-重新认识下Rollup
前端·javascript
m0_7401546718 分钟前
SpringMVC 请求和响应
java·服务器·前端
加减法原则21 分钟前
探索 RAG(检索增强生成)
前端
计算机-秋大田40 分钟前
基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
熬了夜的程序员1 小时前
Go 语言封装邮件发送功能
开发语言·后端·golang·log4j
uhakadotcom1 小时前
PostgreSQL 行级安全性(RLS)简介
后端·面试·github
禁止摆烂_才浅1 小时前
前端开发小技巧 - 【CSS】- 表单控件的 placeholder 如何控制换行显示?
前端·css·html
烂蜻蜓1 小时前
深度解读 C 语言运算符:编程运算的核心工具
java·c语言·前端
PsG喵喵1 小时前
用 Pinia 点燃 Vue 3 应用:状态管理革新之旅
前端·javascript·vue.js