当前位置: 首页 > news >正文

GitHub Actions CI/CD 自动化部署完全指南

GitHub Actions CI/CD 自动化部署完全指南

文章目录

  • GitHub Actions CI/CD 自动化部署完全指南
    • 什么是 CI/CD 和 GitHub Actions
      • CI/CD 概念
      • GitHub Actions 简介
        • 🚀 主要优势
        • 📊 使用统计
    • GitHub Actions 核心概念
      • 基本组件
        • 1. **Workflow(工作流)**
        • 2. **Event(事件)**
        • 3. **Job(作业)**
        • 4. **Step(步骤)**
        • 5. **Action(动作)**
        • 6. **Runner(运行器)**
      • 工作流语法结构
    • 基础工作流配置
      • 创建第一个工作流
        • 1. 创建工作流文件
        • 2. 常用触发事件
        • 3. 环境变量配置
    • 前端项目 CI/CD 实践
      • React 项目完整工作流
      • Vue.js 项目工作流
    • 后端项目 CI/CD 实践
      • Node.js Express 应用
      • Python Django 应用
    • 全栈项目 CI/CD 实践
      • Monorepo 项目结构
    • 安全性和性能优化
      • 安全最佳实践
        • 1. **Secrets 管理**
        • 2. **权限最小化**
        • 3. **依赖安全扫描**
        • 4. **环境隔离和保护**
      • 性能优化策略
        • 1. **缓存优化**
        • 2. **并行执行优化**
        • 3. **资源优化**
    • 常见问题和解决方案
      • 构建和部署问题
        • 1. **依赖安装失败**
        • 2. **Docker 构建失败**
        • 3. **测试超时或失败**
      • 权限和安全问题
        • 1. **权限被拒绝错误**
        • 2. **Secrets 访问问题**
      • 性能问题
        • 1. **构建时间过长**
        • 2. **资源限制问题**
      • 调试技巧
        • 1. **启用调试日志**
        • 2. **条件调试**
    • 总结
      • 关键要点
      • 最佳实践总结
        • ✅ 推荐做法
        • ❌ 避免的做法
      • 进阶学习路径
      • 参考资料
        • 官方文档
        • 社区资源
        • 工具和服务
        • 博客和教程
  • 部署
    • 总结
      • 🎯 核心收获
      • 📈 进阶建议
      • 🔗 有用资源
      • 🚀 下一步行动
  • 部署
      • 条件执行和依赖管理
      • 缓存策略优化
      • 并行任务和工作流复用
    • 安全性和性能优化
      • Secrets 管理最佳实践
        • 1. 环境级别的 Secrets
        • 2. 动态 Secrets 引用
      • 权限最小化原则
      • 安全扫描集成
      • 性能优化策略
        • 1. 并行化优化
        • 2. 智能缓存策略
    • 常见问题和解决方案
      • 问题 1:工作流执行时间过长
      • 问题 2:Secrets 管理混乱
      • 问题 3:依赖冲突和版本问题
      • 问题 4:环境变量和配置管理
      • 问题 5:Docker 构建优化
    • 实用配置模板
      • 模板 1:React + TypeScript 项目
      • 模板 2:Node.js API 项目

什么是 CI/CD 和 GitHub Actions

CI/CD 概念

持续集成(Continuous Integration, CI) 是一种开发实践,开发者频繁地将代码集成到主分支中,每次集成都通过自动化构建来验证,从而尽早发现集成错误。

持续部署(Continuous Deployment, CD) 是在持续集成的基础上,将通过测试的代码自动部署到生产环境的实践。

GitHub Actions 简介

GitHub Actions 是 GitHub 提供的 CI/CD 平台,允许您直接在 GitHub 仓库中自动化软件开发工作流程。

🚀 主要优势
  • 原生集成:与 GitHub 仓库无缝集成
  • 免费额度:公共仓库免费,私有仓库每月 2000 分钟免费
  • 丰富的 Actions 市场:数千个预构建的 Actions 可供使用
  • 多平台支持:支持 Linux、Windows、macOS
  • 灵活配置:支持复杂的工作流程和条件执行
📊 使用统计
GitHub Actions 使用数据:
- 超过 300 万个组织在使用
- 每月执行超过 10 亿次工作流
- 市场中有超过 20,000 个 Actions

GitHub Actions 核心概念

基本组件

1. Workflow(工作流)
  • 定义在 .github/workflows/ 目录下的 YAML 文件
  • 包含一个或多个 Jobs
  • 由特定事件触发
2. Event(事件)
  • 触发工作流的特定活动
  • 常见事件:pushpull_requestscheduleworkflow_dispatch
3. Job(作业)
  • 工作流中的一组步骤
  • 在同一个运行器上执行
  • 可以并行或串行执行
4. Step(步骤)
  • Job 中的单个任务
  • 可以运行命令或使用 Action
5. Action(动作)
  • 可重用的代码单元
  • 可以是自定义的或来自市场
6. Runner(运行器)
  • 执行工作流的服务器
  • GitHub 提供托管运行器,也可以自托管

工作流语法结构

name: 工作流名称# 触发条件
on:push:branches: [ main, develop ]pull_request:branches: [ main ]# 环境变量
env:NODE_VERSION: '18'# 作业定义
jobs:job-name:runs-on: ubuntu-lateststeps:- name: 步骤名称uses: actions/checkout@v4- name: 另一个步骤run: echo "Hello World"

基础工作流配置

创建第一个工作流

1. 创建工作流文件

在项目根目录创建 .github/workflows/ci.yml

name: Basic CI# 触发条件:推送到 main 分支或创建 PR
on:push:branches: [ main ]pull_request:branches: [ main ]jobs:test:name: 运行测试runs-on: ubuntu-lateststeps:# 检出代码- name: Checkout codeuses: actions/checkout@v4# 设置 Node.js 环境- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: '18'cache: 'npm'# 安装依赖- name: Install dependenciesrun: npm ci# 运行测试- name: Run testsrun: npm test# 运行代码检查- name: Run lintingrun: npm run lint
2. 常用触发事件
on:# 推送到指定分支push:branches: [ main, develop ]paths:- 'src/**'- 'package.json'# Pull Requestpull_request:branches: [ main ]types: [opened, synchronize, reopened]# 定时执行schedule:- cron: '0 2 * * *'  # 每天凌晨2点# 手动触发workflow_dispatch:inputs:environment:description: '部署环境'required: truedefault: 'staging'type: choiceoptions:- staging- production# 发布 Releaserelease:types: [published]
3. 环境变量配置
env:# 全局环境变量NODE_VERSION: '18'REGISTRY_URL: 'https://registry.npmjs.org'jobs:build:runs-on: ubuntu-latestenv:# Job 级别环境变量BUILD_ENV: productionsteps:- name: Build applicationenv:# Step 级别环境变量API_URL: ${{ secrets.API_URL }}run: |echo "Node version: $NODE_VERSION"echo "Build environment: $BUILD_ENV"echo "API URL: $API_URL"

前端项目 CI/CD 实践

React 项目完整工作流

name: React App CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]env:NODE_VERSION: '18'REGISTRY_URL: 'https://registry.npmjs.org'jobs:# 代码质量检查quality-check:name: 代码质量检查runs-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}cache: 'npm'registry-url: ${{ env.REGISTRY_URL }}- name: Install dependenciesrun: npm ci- name: Run ESLintrun: npm run lint- name: Run Prettier checkrun: npm run format:check- name: Run type checkrun: npm run type-check- name: Run tests with coveragerun: npm run test:coverage- name: Upload coverage to Codecovuses: codecov/codecov-action@v3with:file: ./coverage/lcov.infoflags: unittestsname: codecov-umbrella# 构建应用build:name: 构建应用runs-on: ubuntu-latestneeds: quality-checkstrategy:matrix:environment: [staging, production]steps:- name: Checkout codeuses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}cache: 'npm'- name: Install dependenciesrun: npm ci- name: Build for ${{ matrix.environment }}env:REACT_APP_ENV: ${{ matrix.environment }}REACT_APP_API_URL: ${{ secrets[format('API_URL_{0}', matrix.environment)] }}run: npm run build- name: Upload build artifactsuses: actions/upload-artifact@v3with:name: build-${{ matrix.environment }}path: build/retention-days: 7# 部署到 Verceldeploy-vercel:name: 部署到 Vercelruns-on: ubuntu-latestneeds: buildif: github.ref == 'refs/heads/main'steps:- name: Checkout codeuses: actions/checkout@v4- name: Download build artifactsuses: actions/download-artifact@v3with:name: build-productionpath: build/- name: Deploy to Verceluses: amondnet/vercel-action@v25with:vercel-token: ${{ secrets.VERCEL_TOKEN }}vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}working-directory: ./vercel-args: '--prod'# 部署到 Netlifydeploy-netlify:name: 部署到 Netlifyruns-on: ubuntu-latestneeds: buildif: github.ref == 'refs/heads/develop'steps:- name: Download build artifactsuses: actions/download-artifact@v3with:name: build-stagingpath: build/- name: Deploy to Netlifyuses: nwtgck/actions-netlify@v2.0with:publish-dir: './build'production-branch: maingithub-token: ${{ secrets.GITHUB_TOKEN }}deploy-message: "Deploy from GitHub Actions"env:NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

Vue.js 项目工作流

name: Vue.js App CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]jobs:test-and-build:name: 测试和构建runs-on: ubuntu-lateststrategy:matrix:node-version: [16, 18, 20]steps:- uses: actions/checkout@v4- name: Setup Node.js ${{ matrix.node-version }}uses: actions/setup-node@v4with:node-version: ${{ matrix.node-version }}cache: 'npm'- name: Install dependenciesrun: npm ci- name: Run unit testsrun: npm run test:unit- name: Run e2e testsrun: npm run test:e2e:headless- name: Build applicationrun: npm run build- name: Upload build artifactsif: matrix.node-version == 18uses: actions/upload-artifact@v3with:name: vue-buildpath: dist/deploy:name: 部署应用runs-on: ubuntu-latestneeds: test-and-buildif: github.ref == 'refs/heads/main'steps:- name: Download build artifactsuses: actions/download-artifact@v3with:name: vue-buildpath: dist/- name: Deploy to GitHub Pagesuses: peaceiris/actions-gh-pages@v3with:github_token: ${{ secrets.GITHUB_TOKEN }}publish_dir: ./dist

后端项目 CI/CD 实践

Node.js Express 应用

name: Node.js Express API CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]env:NODE_VERSION: '18'DOCKER_REGISTRY: 'ghcr.io'jobs:# 测试阶段test:name: 运行测试runs-on: ubuntu-latestservices:# PostgreSQL 服务postgres:image: postgres:15env:POSTGRES_PASSWORD: postgresPOSTGRES_DB: test_dboptions: >---health-cmd pg_isready--health-interval 10s--health-timeout 5s--health-retries 5ports:- 5432:5432# Redis 服务redis:image: redis:7options: >---health-cmd "redis-cli ping"--health-interval 10s--health-timeout 5s--health-retries 5ports:- 6379:6379steps:- name: Checkout codeuses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}cache: 'npm'- name: Install dependenciesrun: npm ci- name: Run database migrationsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_dbrun: npm run db:migrate- name: Run unit testsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_dbREDIS_URL: redis://localhost:6379run: npm run test- name: Run integration testsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_dbREDIS_URL: redis://localhost:6379run: npm run test:integration- name: Generate test coveragerun: npm run test:coverage- name: Upload coverage reportsuses: codecov/codecov-action@v3with:file: ./coverage/lcov.info# 安全扫描security-scan:name: 安全扫描runs-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkout@v4- name: Run npm auditrun: npm audit --audit-level moderate- name: Run Snyk security scanuses: snyk/actions/node@masterenv:SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}with:args: --severity-threshold=high# 构建 Docker 镜像build-docker:name: 构建 Docker 镜像runs-on: ubuntu-latestneeds: [test, security-scan]steps:- name: Checkout codeuses: actions/checkout@v4- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3- name: Login to Container Registryuses: docker/login-action@v3with:registry: ${{ env.DOCKER_REGISTRY }}username: ${{ github.actor }}password: ${{ secrets.GITHUB_TOKEN }}- name: Extract metadataid: metauses: docker/metadata-action@v5with:images: ${{ env.DOCKER_REGISTRY }}/${{ github.repository }}tags: |type=ref,event=branchtype=ref,event=prtype=sha,prefix={{branch}}-type=raw,value=latest,enable={{is_default_branch}}- name: Build and push Docker imageuses: docker/build-push-action@v5with:context: .platforms: linux/amd64,linux/arm64push: truetags: ${{ steps.meta.outputs.tags }}labels: ${{ steps.meta.outputs.labels }}cache-from: type=ghacache-to: type=gha,mode=max# 部署到 stagingdeploy-staging:name: 部署到 Stagingruns-on: ubuntu-latestneeds: build-dockerif: github.ref == 'refs/heads/develop'environment: stagingsteps:- name: Deploy to staging serveruses: appleboy/ssh-action@v1.0.0with:host: ${{ secrets.STAGING_HOST }}username: ${{ secrets.STAGING_USER }}key: ${{ secrets.STAGING_SSH_KEY }}script: |docker pull ${{ env.DOCKER_REGISTRY }}/${{ github.repository }}:developdocker stop api-staging || truedocker rm api-staging || truedocker run -d \--name api-staging \--restart unless-stopped \-p 3000:3000 \-e NODE_ENV=staging \-e DATABASE_URL=${{ secrets.STAGING_DATABASE_URL }} \${{ env.DOCKER_REGISTRY }}/${{ github.repository }}:develop# 部署到 productiondeploy-production:name: 部署到 Productionruns-on: ubuntu-latestneeds: build-dockerif: github.ref == 'refs/heads/main'environment: productionsteps:- name: Deploy to Kubernetesuses: azure/k8s-deploy@v1with:manifests: |k8s/deployment.yamlk8s/service.yamlimages: |${{ env.DOCKER_REGISTRY }}/${{ github.repository }}:latestkubeconfig: ${{ secrets.KUBE_CONFIG }}

Python Django 应用

name: Django App CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]jobs:test:name: 测试 Django 应用runs-on: ubuntu-lateststrategy:matrix:python-version: [3.9, 3.10, 3.11]services:postgres:image: postgres:15env:POSTGRES_PASSWORD: postgresPOSTGRES_DB: django_testoptions: >---health-cmd pg_isready--health-interval 10s--health-timeout 5s--health-retries 5ports:- 5432:5432steps:- uses: actions/checkout@v4- name: Set up Python ${{ matrix.python-version }}uses: actions/setup-python@v4with:python-version: ${{ matrix.python-version }}- name: Install dependenciesrun: |python -m pip install --upgrade pippip install -r requirements.txtpip install -r requirements-dev.txt- name: Run migrationsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/django_testrun: python manage.py migrate- name: Run testsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/django_testrun: |python manage.py testcoverage run --source='.' manage.py testcoverage xml- name: Upload coverage to Codecovuses: codecov/codecov-action@v3with:file: ./coverage.xmldeploy:name: 部署到 Herokuruns-on: ubuntu-latestneeds: testif: github.ref == 'refs/heads/main'steps:- uses: actions/checkout@v4- name: Deploy to Herokuuses: akhileshns/heroku-deploy@v3.12.14with:heroku_api_key: ${{ secrets.HEROKU_API_KEY }}heroku_app_name: "your-django-app"heroku_email: "your-email@example.com"

全栈项目 CI/CD 实践

Monorepo 项目结构

name: Full Stack Monorepo CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]env:NODE_VERSION: '18'PYTHON_VERSION: '3.11'jobs:# 检测变更detect-changes:name: 检测文件变更runs-on: ubuntu-latestoutputs:frontend: ${{ steps.changes.outputs.frontend }}backend: ${{ steps.changes.outputs.backend }}shared: ${{ steps.changes.outputs.shared }}steps:- uses: actions/checkout@v4- uses: dorny/paths-filter@v2id: changeswith:filters: |frontend:- 'frontend/**'- 'shared/**'backend:- 'backend/**'- 'shared/**'shared:- 'shared/**'# 前端测试和构建frontend-ci:name: 前端 CIruns-on: ubuntu-latestneeds: detect-changesif: needs.detect-changes.outputs.frontend == 'true'defaults:run:working-directory: ./frontendsteps:- uses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}cache: 'npm'cache-dependency-path: frontend/package-lock.json- name: Install dependenciesrun: npm ci- name: Run testsrun: npm test- name: Build applicationrun: npm run build- name: Upload build artifactsuses: actions/upload-artifact@v3with:name: frontend-buildpath: frontend/dist/# 后端测试backend-ci:name: 后端 CIruns-on: ubuntu-latestneeds: detect-changesif: needs.detect-changes.outputs.backend == 'true'defaults:run:working-directory: ./backendservices:postgres:image: postgres:15env:POSTGRES_PASSWORD: postgresPOSTGRES_DB: test_dboptions: >---health-cmd pg_isready--health-interval 10s--health-timeout 5s--health-retries 5ports:- 5432:5432steps:- uses: actions/checkout@v4- name: Setup Pythonuses: actions/setup-python@v4with:python-version: ${{ env.PYTHON_VERSION }}- name: Install dependenciesrun: |python -m pip install --upgrade pippip install -r requirements.txt- name: Run testsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_dbrun: pytest# 集成测试integration-test:name: 集成测试runs-on: ubuntu-latestneeds: [frontend-ci, backend-ci]if: always() && (needs.frontend-ci.result == 'success' || needs.frontend-ci.result == 'skipped') && (needs.backend-ci.result == 'success' || needs.backend-ci.result == 'skipped')steps:- uses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}- name: Install Playwrightrun: |npm install -g @playwright/testnpx playwright install- name: Start services with Docker Composerun: docker-compose -f docker-compose.test.yml up -d- name: Wait for servicesrun: |timeout 60 bash -c 'until curl -f http://localhost:3000/health; do sleep 2; done'timeout 60 bash -c 'until curl -f http://localhost:8000/health; do sleep 2; done'- name: Run E2E testsrun: npx playwright test- name: Upload test resultsuses: actions/upload-artifact@v3if: always()with:name: playwright-reportpath: playwright-report/# 部署deploy:name: 部署runs-on: ubuntu-latestneeds: [frontend, backend, e2e]if: github.ref == 'refs/heads/main' && success()steps:- name: Download frontend builduses: actions/download-artifact@v3with:name: frontend-buildpath: frontend-dist/- name: Deploy frontend to CDNrun: |# 部署前端到 CDNecho "Deploying frontend to CDN..."- name: Deploy backend to Kubernetesrun: |# 部署后端到 K8secho "Deploying backend to Kubernetes..."

安全性和性能优化

安全最佳实践

1. Secrets 管理
name: Secure CI/CDon:push:branches: [ main ]jobs:secure-build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4# ✅ 正确的 secrets 使用- name: Configure AWS credentialsuses: aws-actions/configure-aws-credentials@v4with:aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}aws-region: us-east-1# ❌ 错误:不要在日志中暴露敏感信息# - name: Debug secrets#   run: echo "API Key: ${{ secrets.API_KEY }}"# ✅ 正确:使用环境变量- name: Deploy with secretsenv:API_KEY: ${{ secrets.API_KEY }}DATABASE_URL: ${{ secrets.DATABASE_URL }}run: |# 使用环境变量而不是直接引用 secrets./deploy.sh
2. 权限最小化
name: Minimal Permissionson:push:branches: [ main ]# 设置最小权限
permissions:contents: readpackages: writesecurity-events: writejobs:build:runs-on: ubuntu-latest# Job 级别权限覆盖permissions:contents: readpackages: writesteps:- uses: actions/checkout@v4- name: Build and push Docker imageuses: docker/build-push-action@v5with:context: .push: truetags: ghcr.io/${{ github.repository }}:latest
3. 依赖安全扫描
name: Security Scanningon:push:branches: [ main ]pull_request:branches: [ main ]schedule:- cron: '0 6 * * 1'  # 每周一早上6点jobs:security-scan:name: 安全扫描runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4# npm 审计- name: Run npm auditrun: |npm audit --audit-level moderatenpm audit fix --dry-run# Snyk 安全扫描- name: Run Snyk to check for vulnerabilitiesuses: snyk/actions/node@masterenv:SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}with:args: --severity-threshold=high --fail-on=upgradable# CodeQL 代码分析- name: Initialize CodeQLuses: github/codeql-action/init@v2with:languages: javascript, typescript- name: Perform CodeQL Analysisuses: github/codeql-action/analyze@v2# 容器镜像扫描- name: Run Trivy vulnerability scanneruses: aquasecurity/trivy-action@masterwith:image-ref: 'myapp:latest'format: 'sarif'output: 'trivy-results.sarif'- name: Upload Trivy scan resultsuses: github/codeql-action/upload-sarif@v2with:sarif_file: 'trivy-results.sarif'
4. 环境隔离和保护
name: Environment Protectionon:push:branches: [ main, develop ]jobs:deploy-staging:name: 部署到 Stagingruns-on: ubuntu-latestenvironment: stagingif: github.ref == 'refs/heads/develop'steps:- name: Deploy to stagingrun: echo "Deploying to staging environment"deploy-production:name: 部署到 Productionruns-on: ubuntu-latestenvironment: name: productionurl: https://myapp.comif: github.ref == 'refs/heads/main'steps:- name: Deploy to productionrun: echo "Deploying to production environment"

性能优化策略

1. 缓存优化
name: Optimized Cachingon:push:branches: [ main ]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4# Node.js 依赖缓存- name: Setup Node.js with cacheuses: actions/setup-node@v4with:node-version: '18'cache: 'npm'cache-dependency-path: |package-lock.jsonfrontend/package-lock.jsonbackend/package-lock.json# 自定义缓存- name: Cache node modulesuses: actions/cache@v3with:path: |~/.npmnode_modules*/node_moduleskey: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}restore-keys: |${{ runner.os }}-node-# Docker 层缓存- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3- name: Build with cacheuses: docker/build-push-action@v5with:context: .cache-from: type=ghacache-to: type=gha,mode=maxpush: truetags: myapp:latest
2. 并行执行优化
name: Parallel Executionon:push:branches: [ main ]jobs:# 并行测试矩阵test:name: 测试runs-on: ubuntu-lateststrategy:matrix:node-version: [16, 18, 20]test-suite: [unit, integration, e2e]fail-fast: false  # 不因单个失败而停止所有任务max-parallel: 6   # 最大并行数steps:- uses: actions/checkout@v4- name: Setup Node.js ${{ matrix.node-version }}uses: actions/setup-node@v4with:node-version: ${{ matrix.node-version }}cache: 'npm'- name: Install dependenciesrun: npm ci- name: Run ${{ matrix.test-suite }} testsrun: npm run test:${{ matrix.test-suite }}# 并行构建不同平台build:name: 构建runs-on: ubuntu-latestneeds: teststrategy:matrix:platform: [linux/amd64, linux/arm64]steps:- uses: actions/checkout@v4- name: Set up QEMUuses: docker/setup-qemu-action@v3- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3- name: Build for ${{ matrix.platform }}uses: docker/build-push-action@v5with:context: .platforms: ${{ matrix.platform }}push: truetags: myapp:${{ matrix.platform }}
3. 资源优化
name: Resource Optimizationon:push:branches: [ main ]jobs:optimized-build:name: 优化构建runs-on: ubuntu-latest# 设置超时时间timeout-minutes: 30steps:- uses: actions/checkout@v4with:# 浅克隆以减少下载时间fetch-depth: 1# 只在需要时安装依赖- name: Check if dependencies changeduses: dorny/paths-filter@v2id: changeswith:filters: |deps:- 'package*.json'- 'yarn.lock'- name: Setup Node.jsif: steps.changes.outputs.deps == 'true'uses: actions/setup-node@v4with:node-version: '18'cache: 'npm'- name: Install dependenciesif: steps.changes.outputs.deps == 'true'run: npm ci --prefer-offline --no-audit# 条件执行构建- name: Build applicationif: steps.changes.outputs.deps == 'true' || github.event_name == 'push'run: npm run build

常见问题和解决方案

构建和部署问题

1. 依赖安装失败

问题描述npm cinpm install 失败

常见原因和解决方案

# 解决方案 1:清理缓存
- name: Clear npm cacherun: npm cache clean --force- name: Install dependenciesrun: npm ci# 解决方案 2:使用不同的 registry
- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: '18'registry-url: 'https://registry.npmmirror.com'# 解决方案 3:忽略可选依赖
- name: Install dependenciesrun: npm ci --no-optional# 解决方案 4:增加超时时间
- name: Install dependenciesrun: npm ci --timeout=300000
2. Docker 构建失败

问题描述:Docker 镜像构建过程中出错

# 解决方案 1:多阶段构建优化
# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --forceFROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "start"]# 解决方案 2:增加构建资源
- name: Build Docker imageuses: docker/build-push-action@v5with:context: .push: truetags: myapp:latestbuild-args: |BUILDKIT_INLINE_CACHE=1cache-from: type=ghacache-to: type=gha,mode=max
3. 测试超时或失败
# 解决方案 1:增加测试超时时间
- name: Run testsrun: npm testtimeout-minutes: 10# 解决方案 2:并行测试
- name: Run tests in parallelrun: npm test -- --maxWorkers=2# 解决方案 3:重试机制
- name: Run tests with retryuses: nick-invision/retry@v2with:timeout_minutes: 5max_attempts: 3command: npm test

权限和安全问题

1. 权限被拒绝错误
# 问题:Permission denied
# 解决方案:设置正确的权限
permissions:contents: readpackages: writedeployments: write# 或者在 job 级别设置
jobs:deploy:runs-on: ubuntu-latestpermissions:contents: readpackages: writesteps:# ...
2. Secrets 访问问题
# 问题:无法访问 secrets
# 解决方案 1:检查 secrets 名称
- name: Use secretenv:API_KEY: ${{ secrets.API_KEY }}  # 确保名称正确run: echo "Using API key"# 解决方案 2:环境级别的 secrets
jobs:deploy:environment: production  # 使用环境级别的 secretssteps:- name: Deployenv:DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}run: ./deploy.sh

性能问题

1. 构建时间过长
# 解决方案 1:使用缓存
- name: Cache dependenciesuses: actions/cache@v3with:path: ~/.npmkey: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}# 解决方案 2:并行构建
strategy:matrix:component: [frontend, backend, api]max-parallel: 3# 解决方案 3:条件执行
- name: Build only if changedif: steps.changes.outputs.src == 'true'run: npm run build
2. 资源限制问题
# 解决方案 1:使用更大的运行器
jobs:build:runs-on: ubuntu-latest-4-cores  # 使用更多 CPU 核心# 解决方案 2:优化内存使用
- name: Build with memory optimizationrun: |export NODE_OPTIONS="--max-old-space-size=4096"npm run build

调试技巧

1. 启用调试日志
# 启用 Actions 调试
- name: Debug informationrun: |echo "Runner OS: ${{ runner.os }}"echo "GitHub ref: ${{ github.ref }}"echo "Event name: ${{ github.event_name }}"env# 启用 npm 调试
- name: Install with debugrun: npm ci --loglevel verbose# 启用 Docker 调试
- name: Build Docker with debugrun: |export DOCKER_BUILDKIT=1export BUILDKIT_PROGRESS=plaindocker build --progress=plain .
2. 条件调试
- name: Debug on failureif: failure()run: |echo "Build failed, collecting debug info..."ls -lacat package.jsonnpm ls --depth=0

总结

关键要点

  1. 渐进式采用:从简单的 CI 开始,逐步添加 CD 功能
  2. 安全第一:始终遵循安全最佳实践,保护敏感信息
  3. 性能优化:合理使用缓存和并行执行提高效率
  4. 监控和反馈:建立完善的监控和通知机制
  5. 文档化:维护清晰的工作流文档和最佳实践

最佳实践总结

✅ 推荐做法
  • 使用语义化的工作流和作业名称
  • 合理设置触发条件,避免不必要的执行
  • 充分利用缓存机制提高构建速度
  • 实施全面的测试策略(单元测试、集成测试、E2E 测试)
  • 使用环境保护和审批流程
  • 定期更新 Actions 版本
  • 监控工作流执行时间和成本
❌ 避免的做法
  • 在日志中暴露敏感信息
  • 使用过于宽泛的权限
  • 忽略安全扫描和依赖更新
  • 创建过于复杂的单一工作流
  • 缺乏错误处理和重试机制
  • 不使用环境变量管理配置

进阶学习路径

  1. 基础阶段

    • 掌握 YAML 语法和 GitHub Actions 基本概念
    • 创建简单的 CI 工作流
    • 学习常用的官方 Actions
  2. 中级阶段

    • 实现完整的 CI/CD 流水线
    • 掌握矩阵构建和并行执行
    • 学习 Docker 集成和容器化部署
  3. 高级阶段

    • 创建自定义 Actions
    • 实现复杂的部署策略(蓝绿部署、金丝雀发布)
    • 集成监控和可观测性工具

参考资料

官方文档
  • GitHub Actions 官方文档
  • 工作流语法参考
  • Actions 市场
社区资源
  • Awesome GitHub Actions
  • GitHub Actions 最佳实践
  • Actions 示例仓库
工具和服务
  • Act - 本地运行 GitHub Actions
  • GitHub Actions Toolkit
  • Dependabot - 依赖更新自动化
博客和教程
  • GitHub Blog - Actions 相关文章
  • DevOps 最佳实践指南
  • CI/CD 模式和实践

结语

GitHub Actions 为现代软件开发提供了强大而灵活的 CI/CD 解决方案。通过本指南的学习和实践,您应该能够:

  • 理解 CI/CD 的核心概念和价值
  • 掌握 GitHub Actions 的基本使用方法
  • 为不同类型的项目设计合适的工作流
  • 实施安全和性能最佳实践
  • 解决常见的构建和部署问题

记住,CI/CD 是一个持续改进的过程。随着项目的发展和团队的成长,您的工作流也应该不断优化和完善。保持学习新的工具和实践,关注社区的最新发展,这将帮助您构建更加高效和可靠的软件交付流水线。

Happy Coding! 🚀
name: playwright-report
path: playwright-report/

部署

deploy:
name: 部署
runs-on: ubuntu-latest
needs: [frontend, backend, e2e]
if: github.ref == ‘refs/heads/main’ && success()

steps:
- name: Download frontend builduses: actions/download-artifact@v3with:name: frontend-buildpath: frontend-dist/- name: Deploy frontend to CDNrun: |# 部署前端到 CDNecho "Deploying frontend to CDN..."- name: Deploy backend to Kubernetesrun: |# 部署后端到 K8secho "Deploying backend to Kubernetes..."

### 模板 4:Python Django 项目```yaml
name: Django CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]env:PYTHON_VERSION: '3.11'jobs:test:name: 测试runs-on: ubuntu-latestservices:postgres:image: postgres:15env:POSTGRES_PASSWORD: postgresPOSTGRES_DB: django_testoptions: >---health-cmd pg_isready--health-interval 10s--health-timeout 5s--health-retries 5ports:- 5432:5432steps:- uses: actions/checkout@v4- name: Setup Pythonuses: actions/setup-python@v4with:python-version: ${{ env.PYTHON_VERSION }}cache: 'pip'- name: Install dependenciesrun: |python -m pip install --upgrade pippip install -r requirements.txtpip install -r requirements-dev.txt- name: Run migrationsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/django_testrun: python manage.py migrate- name: Run testsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/django_testrun: |coverage run --source='.' manage.py testcoverage xml- name: Upload coverageuses: codecov/codecov-action@v3with:file: ./coverage.xmldeploy:name: 部署到 Herokuruns-on: ubuntu-latestneeds: testif: github.ref == 'refs/heads/main'steps:- uses: actions/checkout@v4- name: Deploy to Herokuuses: akhileshns/heroku-deploy@v3.12.14with:heroku_api_key: ${{ secrets.HEROKU_API_KEY }}heroku_app_name: "your-django-app"heroku_email: "your-email@example.com"

总结

GitHub Actions 作为现代 CI/CD 的重要工具,为开发团队提供了强大而灵活的自动化能力。通过本指南,您应该能够:

🎯 核心收获

  1. 理解 CI/CD 概念:掌握持续集成和持续部署的基本原理
  2. 熟练使用 GitHub Actions:了解工作流、作业、步骤等核心概念
  3. 实践最佳实践:应用安全性、性能优化和错误处理策略
  4. 解决常见问题:快速诊断和解决工作流中的典型问题

📈 进阶建议

  1. 持续学习:关注 GitHub Actions 的新功能和社区最佳实践
  2. 监控优化:定期审查工作流性能,优化执行时间和资源使用
  3. 安全第一:始终遵循安全最佳实践,保护敏感信息
  4. 团队协作:建立团队 CI/CD 规范,确保一致性

🔗 有用资源

  • GitHub Actions 官方文档
  • GitHub Actions 市场
  • Awesome GitHub Actions
  • GitHub Actions 社区论坛

🚀 下一步行动

  1. 选择适合您项目的模板开始实践
  2. 根据项目需求定制工作流
  3. 逐步添加高级功能和优化
  4. 与团队分享经验和最佳实践

记住,优秀的 CI/CD 流程不是一蹴而就的,需要持续改进和优化。从简单开始,逐步完善,最终构建出适合您团队的完美自动化流程。


本指南将持续更新,以反映 GitHub Actions 的最新功能和社区最佳实践。如有问题或建议,欢迎提出反馈。
name: playwright-report
path: playwright-report/

部署

deploy:
name: 部署应用
runs-on: ubuntu-latest
needs: [frontend-ci, backend-ci, integration-test]
if: github.ref == ‘refs/heads/main’ && success()

steps:
- uses: actions/checkout@v4- name: Download frontend builduses: actions/download-artifact@v3with:name: frontend-buildpath: frontend/dist/- name: Deploy to AWSenv:AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}AWS_REGION: us-east-1run: |# 部署前端到 S3aws s3 sync frontend/dist/ s3://your-frontend-bucket --delete# 部署后端到 ECSaws ecs update-service --cluster your-cluster --service your-service --force-new-deployment

---## 高级功能和最佳实践### 矩阵构建策略```yaml
name: Matrix Build Strategyon: [push, pull_request]jobs:test:name: Test on ${{ matrix.os }} with Node ${{ matrix.node-version }}runs-on: ${{ matrix.os }}strategy:# 失败时不停止其他任务fail-fast: falsematrix:os: [ubuntu-latest, windows-latest, macos-latest]node-version: [16, 18, 20]# 排除特定组合exclude:- os: windows-latestnode-version: 16# 包含特定组合include:- os: ubuntu-latestnode-version: 21experimental: true# 允许实验性构建失败continue-on-error: ${{ matrix.experimental || false }}steps:- uses: actions/checkout@v4- name: Setup Node.js ${{ matrix.node-version }}uses: actions/setup-node@v4with:node-version: ${{ matrix.node-version }}- name: Install dependenciesrun: npm ci- name: Run testsrun: npm test

条件执行和依赖管理

name: Conditional Executionon:push:branches: [ main ]pull_request:branches: [ main ]jobs:# 基础检查lint:name: 代码检查runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Run lintingrun: npm run lint# 单元测试unit-test:name: 单元测试runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Run unit testsrun: npm run test:unit# 集成测试(依赖于前面的任务)integration-test:name: 集成测试runs-on: ubuntu-latestneeds: [lint, unit-test]steps:- uses: actions/checkout@v4- name: Run integration testsrun: npm run test:integration# 构建(只在主分支)build:name: 构建应用runs-on: ubuntu-latestneeds: [lint, unit-test]if: github.ref == 'refs/heads/main'steps:- uses: actions/checkout@v4- name: Build applicationrun: npm run build# 部署(只在构建成功后)deploy:name: 部署应用runs-on: ubuntu-latestneeds: [build, integration-test]if: success() && github.ref == 'refs/heads/main'environment: productionsteps:- name: Deploy to productionrun: echo "Deploying to production..."# 通知(总是执行)notify:name: 发送通知runs-on: ubuntu-latestneeds: [deploy]if: always()steps:- name: Send notificationenv:STATUS: ${{ needs.deploy.result }}run: |if [ "$STATUS" == "success" ]; thenecho "部署成功!"elseecho "部署失败!"fi

缓存策略优化

name: Advanced Cachingon: [push, pull_request]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4# Node.js 依赖缓存- name: Setup Node.js with cacheuses: actions/setup-node@v4with:node-version: '18'cache: 'npm'# 自定义缓存- name: Cache node modulesuses: actions/cache@v3with:path: |~/.npmnode_modules*/*/node_moduleskey: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}restore-keys: |${{ runner.os }}-node-# 构建缓存- name: Cache build outputuses: actions/cache@v3with:path: |.next/cachedistbuildkey: ${{ runner.os }}-build-${{ github.sha }}restore-keys: |${{ runner.os }}-build-# Docker 层缓存- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3- name: Build Docker image with cacheuses: docker/build-push-action@v5with:context: .cache-from: type=ghacache-to: type=gha,mode=maxtags: myapp:latest

并行任务和工作流复用

# .github/workflows/reusable-test.yml
name: Reusable Test Workflowon:workflow_call:inputs:node-version:required: truetype: stringworking-directory:required: falsetype: stringdefault: '.'secrets:NPM_TOKEN:required: falsejobs:test:runs-on: ubuntu-latestdefaults:run:working-directory: ${{ inputs.working-directory }}steps:- uses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ inputs.node-version }}registry-url: 'https://registry.npmjs.org'- name: Install dependenciesenv:NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}run: npm ci- name: Run testsrun: npm test
# .github/workflows/main.yml
name: Main Workflowon: [push, pull_request]jobs:# 使用可复用工作流test-frontend:uses: ./.github/workflows/reusable-test.ymlwith:node-version: '18'working-directory: './frontend'secrets:NPM_TOKEN: ${{ secrets.NPM_TOKEN }}test-backend:uses: ./.github/workflows/reusable-test.ymlwith:node-version: '18'working-directory: './backend'# 并行执行多个任务parallel-tasks:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Run parallel commandsrun: |# 后台运行多个命令npm run lint &npm run type-check &npm run test:unit &# 等待所有后台任务完成wait

安全性和性能优化

Secrets 管理最佳实践

1. 环境级别的 Secrets
name: Secure Deploymenton:push:branches: [ main ]jobs:deploy-staging:runs-on: ubuntu-latestenvironment: stagingsteps:- name: Deploy to stagingenv:# 环境特定的 secretsAPI_KEY: ${{ secrets.STAGING_API_KEY }}DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}run: |echo "Deploying to staging with secure credentials"deploy-production:runs-on: ubuntu-latestenvironment: production# 需要手动批准steps:- name: Deploy to productionenv:API_KEY: ${{ secrets.PRODUCTION_API_KEY }}DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}run: |echo "Deploying to production with secure credentials"
2. 动态 Secrets 引用
jobs:deploy:runs-on: ubuntu-lateststrategy:matrix:environment: [staging, production]steps:- name: Deploy to ${{ matrix.environment }}env:# 动态引用不同环境的 secretsAPI_KEY: ${{ secrets[format('{0}_API_KEY', matrix.environment)] }}DB_URL: ${{ secrets[format('{0}_DATABASE_URL', matrix.environment)] }}run: |echo "Deploying to ${{ matrix.environment }}"

权限最小化原则

name: Minimal Permissionson: [push, pull_request]# 全局权限设置
permissions:contents: readjobs:test:runs-on: ubuntu-latest# 作业级别权限permissions:contents: readchecks: writesteps:- uses: actions/checkout@v4- name: Run testsrun: npm testpublish:runs-on: ubuntu-latestif: github.ref == 'refs/heads/main'permissions:contents: readpackages: writesteps:- uses: actions/checkout@v4- name: Publish packagerun: npm publish

安全扫描集成

name: Security Scanningon:push:branches: [ main ]pull_request:branches: [ main ]schedule:- cron: '0 2 * * 1'  # 每周一凌晨2点jobs:# 依赖漏洞扫描dependency-scan:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Run npm auditrun: npm audit --audit-level moderate- name: Snyk security scanuses: snyk/actions/node@masterenv:SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}with:args: --severity-threshold=highcommand: test# 代码安全扫描code-scan:runs-on: ubuntu-latestpermissions:security-events: writesteps:- uses: actions/checkout@v4- name: Initialize CodeQLuses: github/codeql-action/init@v2with:languages: javascript, typescript- name: Autobuilduses: github/codeql-action/autobuild@v2- name: Perform CodeQL Analysisuses: github/codeql-action/analyze@v2# Docker 镜像安全扫描docker-scan:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Build Docker imagerun: docker build -t myapp:latest .- name: Scan Docker imageuses: aquasecurity/trivy-action@masterwith:image-ref: 'myapp:latest'format: 'sarif'output: 'trivy-results.sarif'- name: Upload Trivy scan resultsuses: github/codeql-action/upload-sarif@v2with:sarif_file: 'trivy-results.sarif'

性能优化策略

1. 并行化优化
name: Performance Optimizedon: [push, pull_request]jobs:# 快速反馈任务quick-checks:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Quick lint checkrun: npm run lint:fast- name: Type checkrun: npm run type-check# 并行测试test:runs-on: ubuntu-lateststrategy:matrix:shard: [1, 2, 3, 4]steps:- uses: actions/checkout@v4- name: Run test shard ${{ matrix.shard }}run: npm run test -- --shard=${{ matrix.shard }}/4# 并行构建build:runs-on: ubuntu-lateststrategy:matrix:target: [web, mobile, desktop]steps:- uses: actions/checkout@v4- name: Build ${{ matrix.target }}run: npm run build:${{ matrix.target }}
2. 智能缓存策略
name: Smart Cachingon: [push, pull_request]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4# 分层缓存策略- name: Cache dependenciesuses: actions/cache@v3with:path: node_moduleskey: deps-${{ runner.os }}-${{ hashFiles('package-lock.json') }}restore-keys: deps-${{ runner.os }}-- name: Cache build artifactsuses: actions/cache@v3with:path: |.next/cachedistkey: build-${{ runner.os }}-${{ github.sha }}restore-keys: |build-${{ runner.os }}-${{ github.ref_name }}-build-${{ runner.os }}-# 条件性安装- name: Install dependenciesif: steps.cache-deps.outputs.cache-hit != 'true'run: npm ci# 增量构建- name: Build applicationrun: |if [ -d "dist" ]; thenecho "Using incremental build"npm run build:incrementalelseecho "Full build required"npm run buildfi

常见问题和解决方案

问题 1:工作流执行时间过长

症状

  • 工作流执行超过 30 分钟
  • 频繁超时失败
  • 资源使用效率低

解决方案

name: Optimized Workflowon: [push, pull_request]jobs:# 1. 使用并行执行test:runs-on: ubuntu-lateststrategy:matrix:shard: [1, 2, 3, 4]steps:- uses: actions/checkout@v4- name: Run tests in parallelrun: npm run test -- --shard=${{ matrix.shard }}/4# 2. 优化缓存策略build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Restore cacheuses: actions/cache@v3with:path: |node_modules~/.npmkey: ${{ runner.os }}-${{ hashFiles('package-lock.json') }}# 3. 使用更快的包管理器- name: Setup pnpmuses: pnpm/action-setup@v2with:version: 8- name: Install dependenciesrun: pnpm install --frozen-lockfile# 4. 条件执行deploy:runs-on: ubuntu-latestif: github.ref == 'refs/heads/main' && github.event_name == 'push'steps:- name: Deploy only when necessaryrun: echo "Deploying..."

问题 2:Secrets 管理混乱

症状

  • Secrets 命名不规范
  • 环境间 Secrets 混用
  • 安全性问题

解决方案

name: Proper Secrets Managementon: [push]jobs:deploy:runs-on: ubuntu-lateststrategy:matrix:environment: [staging, production]environment: ${{ matrix.environment }}steps:- name: Deploy with proper secretsenv:# 使用环境特定的 secretsAPI_KEY: ${{ secrets.API_KEY }}DATABASE_URL: ${{ secrets.DATABASE_URL }}# 或者使用动态引用DYNAMIC_SECRET: ${{ secrets[format('{0}_SECRET', matrix.environment)] }}run: |echo "Deploying to ${{ matrix.environment }}"echo "API Key length: ${#API_KEY}"

Secrets 命名规范

# 环境特定
STAGING_API_KEY
PRODUCTION_API_KEY# 服务特定
GITHUB_TOKEN
DOCKER_REGISTRY_TOKEN
AWS_ACCESS_KEY_ID# 功能特定
CODECOV_TOKEN
SNYK_TOKEN

问题 3:依赖冲突和版本问题

症状

  • 不同环境构建结果不一致
  • 依赖版本冲突
  • 构建失败

解决方案

name: Dependency Managementon: [push, pull_request]jobs:test:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4# 1. 锁定 Node.js 版本- name: Setup Node.jsuses: actions/setup-node@v4with:node-version-file: '.nvmrc'  # 使用项目指定版本cache: 'npm'# 2. 使用精确的依赖安装- name: Install dependenciesrun: |# 使用 ci 而不是 installnpm ci# 验证依赖完整性npm audit --audit-level moderate# 3. 版本一致性检查- name: Check dependency versionsrun: |npm ls --depth=0npm outdated || true# 4. 多版本测试multi-version-test:runs-on: ubuntu-lateststrategy:matrix:node-version: [16, 18, 20]steps:- uses: actions/checkout@v4- name: Setup Node.js ${{ matrix.node-version }}uses: actions/setup-node@v4with:node-version: ${{ matrix.node-version }}- name: Test compatibilityrun: |npm cinpm test

问题 4:环境变量和配置管理

症状

  • 环境变量混乱
  • 配置在不同环境不一致
  • 敏感信息泄露

解决方案

name: Environment Managementon: [push]env:# 全局环境变量NODE_ENV: productionLOG_LEVEL: infojobs:deploy:runs-on: ubuntu-lateststrategy:matrix:environment: [staging, production]environment: ${{ matrix.environment }}steps:- uses: actions/checkout@v4# 1. 环境特定配置- name: Setup environment configrun: |case "${{ matrix.environment }}" instaging)echo "API_URL=https://api-staging.example.com" >> $GITHUB_ENVecho "DEBUG=true" >> $GITHUB_ENV;;production)echo "API_URL=https://api.example.com" >> $GITHUB_ENVecho "DEBUG=false" >> $GITHUB_ENV;;esac# 2. 配置验证- name: Validate configurationenv:DATABASE_URL: ${{ secrets.DATABASE_URL }}run: |# 检查必需的环境变量required_vars=("API_URL" "DATABASE_URL" "NODE_ENV")for var in "${required_vars[@]}"; doif [ -z "${!var}" ]; thenecho "Error: $var is not set"exit 1fidone# 3. 安全的配置文件生成- name: Generate config fileenv:API_KEY: ${{ secrets.API_KEY }}run: |cat > config.json << EOF{"environment": "${{ matrix.environment }}","apiUrl": "$API_URL","debug": $DEBUG,"version": "${{ github.sha }}"}EOF# 不在日志中显示敏感信息echo "Config file generated successfully"

问题 5:Docker 构建优化

症状

  • Docker 构建时间过长
  • 镜像体积过大
  • 缓存效率低

解决方案

name: Optimized Docker Buildon: [push]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4# 1. 设置 Docker Buildx- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3# 2. 登录到镜像仓库- name: Login to registryuses: docker/login-action@v3with:registry: ghcr.iousername: ${{ github.actor }}password: ${{ secrets.GITHUB_TOKEN }}# 3. 优化的多阶段构建- name: Build and pushuses: docker/build-push-action@v5with:context: .file: ./Dockerfile.optimizedplatforms: linux/amd64,linux/arm64push: truetags: |ghcr.io/${{ github.repository }}:latestghcr.io/${{ github.repository }}:${{ github.sha }}# 使用 GitHub Actions 缓存cache-from: type=ghacache-to: type=gha,mode=max# 构建参数build-args: |NODE_VERSION=18BUILD_DATE=${{ github.event.head_commit.timestamp }}VCS_REF=${{ github.sha }}

优化的 Dockerfile

# Dockerfile.optimized
FROM node:18-alpine AS base
WORKDIR /app
COPY package*.json ./FROM base AS deps
RUN npm ci --only=production && npm cache clean --forceFROM base AS build
RUN npm ci
COPY . .
RUN npm run buildFROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package*.json ./EXPOSE 3000
CMD ["npm", "start"]

实用配置模板

模板 1:React + TypeScript 项目

name: React TypeScript CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]env:NODE_VERSION: '18'CACHE_KEY_PREFIX: 'react-app'jobs:# 代码质量检查quality:name: 代码质量检查runs-on: ubuntu-lateststeps:- name: Checkoutuses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}cache: 'npm'- name: Install dependenciesrun: npm ci- name: Type checkrun: npm run type-check- name: Lintrun: npm run lint- name: Format checkrun: npm run format:check- name: Unit testsrun: npm run test:coverage- name: Upload coverageuses: codecov/codecov-action@v3with:file: ./coverage/lcov.info# 构建build:name: 构建应用runs-on: ubuntu-latestneeds: qualitysteps:- name: Checkoutuses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}cache: 'npm'- name: Install dependenciesrun: npm ci- name: Buildrun: npm run build- name: Upload build artifactsuses: actions/upload-artifact@v3with:name: build-filespath: build/retention-days: 7# 部署deploy:name: 部署到 Vercelruns-on: ubuntu-latestneeds: buildif: github.ref == 'refs/heads/main'steps:- name: Checkoutuses: actions/checkout@v4- name: Deploy to Verceluses: amondnet/vercel-action@v25with:vercel-token: ${{ secrets.VERCEL_TOKEN }}vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}vercel-args: '--prod'

模板 2:Node.js API 项目

name: Node.js API CI/CDon:push:branches: [ main, develop ]pull_request:branches: [ main ]env:NODE_VERSION: '18'REGISTRY: ghcr.ioIMAGE_NAME: ${{ github.repository }}jobs:# 测试test:name: 测试runs-on: ubuntu-latestservices:postgres:image: postgres:15env:POSTGRES_PASSWORD: postgresPOSTGRES_DB: test_dboptions: >---health-cmd pg_isready--health-interval 10s--health-timeout 5s--health-retries 5ports:- 5432:5432steps:- name: Checkoutuses: actions/checkout@v4- name: Setup Node.jsuses: actions/setup-node@v4with:node-version: ${{ env.NODE_VERSION }}cache: 'npm'- name: Install dependenciesrun: npm ci- name: Run migrationsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_dbrun: npm run db:migrate- name: Run testsenv:DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_dbrun: npm run test:coverage- name: Upload coverageuses: codecov/codecov-action@v3# 构建 Docker 镜像build:name: 构建镜像runs-on: ubuntu-latestneeds: teststeps:- name: Checkoutuses: actions/checkout@v4- name: Setup Docker Buildxuses: docker/setup-buildx-action@v3- name: Login to registryuses: docker/login-action@v3with:registry: ${{ env.REGISTRY }}username: ${{ github.actor }}password: ${{ secrets.GITHUB_TOKEN }}- name: Extract metadataid: metauses: docker/metadata-action@v5with:images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}tags: |type=ref,event=branchtype=ref,event=prtype=sha- name: Build and pushuses: docker/build-push-action@v5with:context: .push: truetags: ${{ steps.meta.outputs.tags }}labels: ${{ steps.meta.outputs.labels }}cache-from: type=ghacache-to: type=gha,mode=max# 部署deploy:name: 部署runs-on: ubuntu-latestneeds: buildif: github.ref == 'refs/heads/main'environment: productionsteps:- name: Deploy to serveruses: appleboy/ssh-action@v1.0.0with:host: ${{ secrets.HOST }}username: ${{ secrets.USERNAME }}key: ${{ secrets.SSH_KEY }}script: |docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:maindocker stop api || truedocker rm api || truedocker run -d \--name api \--restart unless-stopped \-p 3000:3000 \-e DATABASE_URL=${{ secrets.DATABASE_URL }} \${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main

本指南涵盖了 GitHub Actions CI/CD 的核心概念、实践案例和最佳实践。通过学习和应用这些知识,您将能够构建高效、安全、可靠的自动化部署流程。

http://www.dtcms.com/a/548761.html

相关文章:

  • Fastlane 结合 开心上架 命令行版本实现跨平台上传发布 iOS App
  • 广东营销网站建设服务公司军事信息化建设网站
  • Go Web 编程快速入门 14 - 性能优化与最佳实践:Go应用性能分析、内存管理、并发编程最佳实践
  • LeetCode每日一题——合并两个有序链表
  • 丽江市建设局官方网站门户网站开发需要多少钱
  • 边缘计算中评估多模态分类任务的延迟
  • 11.9.16.Filter(过滤器)
  • 光储充微电网能量管理系统:构建绿色、高效、安全的能源未来
  • MR30分布式IO在自动上料机的应用
  • 有些网站为什么可以做资讯建站工具交流
  • .NET周刊【10月第2期 2025-10-12】
  • 自动化文献引用和交叉引用高亮显示:Word VBA宏解决方案
  • 大数据离线处理:使用 Airflow 调度 Hive 脚本的工作流设计
  • 深入理解二叉搜索树:从原理到实现
  • Rust 泛型参数的实践与思考
  • AppML 案例:Employees 应用解析
  • 【Qt开发】布局管理器(一)-> QVBoxLayout垂直布局
  • CF练习记录~
  • 自动化测试 | 认识接口自动化封装中的YAML用例
  • dedecms做门户网站石家庄网站建站
  • windows系统下docker desktop创建容器指定ip
  • 微网站建设费用预算旅游网站开发的需求
  • Ionic + Angular 跨端实战:用 Capacitor 实现相机拍照功能并适配移动端
  • Python 爬虫:从基础到实战的完整指南
  • Angular【http服务端交互】
  • Angular【核心特性】
  • 做seo前景怎么样郑州企业网站优化多少钱
  • 华为 USG 防火墙 NAT 配置
  • uni-app App更新升级前端实现
  • 数据通信领域的专业认证——华为数通认证