GitHub Actions 自动化部署实战:从 Push 到生产环境的完整 CI/CD 流水线

在现代软件开发中,自动化部署已经成为提升研发效率的关键环节。本文将带你从零开始,使用 GitHub Actions 构建一套完整的 CI/CD 流水线,实现代码推送后自动测试、构建并部署到生产服务器。

为什么需要 CI/CD?

传统手动部署存在以下痛点:

  • 重复操作耗时且容易出错
  • 部署回滚困难,无法快速恢复
  • 缺乏统一的代码质量检查
  • 团队协作缺乏标准化流程

GitHub Actions 是 GitHub 内置的 CI/CD 工具,完全免费且与代码仓库无缝集成,是个人开发者和小型团队的最佳选择。

核心概念:Workflow、Job、Step

GitHub Actions 的执行模型分为三个层级:

  • Workflow(工作流):定义在 .github/workflows/ 目录下,可触发多个 Job
  • Job(任务):由多个 Step 组成,默认并行执行(可通过 needs 设置依赖)
  • Step(步骤):执行具体的 Action 或 Shell 命令

实战一:自动化测试与构建

首先创建一个基础的 Node.js 项目流水线,实现每次 Push 后自动运行测试:

name: Node.js CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run linter
        run: npm run lint
      
      - name: Run tests
        run: npm test
      
      - name: Build
        run: npm run build
        if: github.ref == 'refs/heads/main'
      
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/
          retention-days: 7

实战二:自动化部署到服务器

测试通过后,我们需要将构建产物部署到服务器。使用 ssh-actionrsync 实现安全的远程部署:

name: Deploy to Server

on:
  workflow_run:
    workflows: ["Node.js CI"]
    types: [completed]
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/
      
      - name: Deploy to server
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          password: ${{ secrets.SERVER_PASSWORD }}
          port: 22
          script: |
            cd /var/www/myapp
            git pull origin main
            npm ci --production
            pm2 restart myapp
            pm2 logs --lines 10

⚠️ 安全提示:服务器凭证必须存储在 GitHub Secrets 中,切勿硬编码在 YAML 文件中。Secrets 可以在仓库 Settings → Secrets and variables → Actions 中添加。

实战三:多环境部署(Staging + Production)

成熟的团队通常有多个环境,我们来构建一个支持灰度发布的流水线:

name: Multi-Environment Deploy

on:
  push:
    branches:
      - develop  # 部署到 Staging
      - main     # 部署到 Production

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    environment: staging
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to Staging
        run: |
          echo "Deploying to Staging environment..."
          # 模拟部署命令
          curl -X POST ${{ secrets.STAGING_WEBHOOK }}

  deploy-production:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    needs: deploy-staging
    environment: production
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Run migration
        run: |
          echo "Running database migrations..."
          # 实际项目中运行 migration 脚本
          npm run migrate:prod
      
      - name: Deploy to Production
        run: |
          echo "Deploying to Production..."
          # 生产环境部署命令
          npm run deploy:prod
      
      - name: Notify team
        if: always()
        run: |
          echo "Deployment status: ${{ job.status }}"

实战四:使用 Docker 构建并推送镜像

容器化部署是现代应用的主流方式。以下配置实现代码推送后自动构建并推送 Docker 镜像:

name: Docker Build and Push

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

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}
      
      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: myusername/myapp
          tags: |
            type=sha,prefix=
            type=ref,event=branch
            type=semver,pattern={{version}}
      
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: ${{ github.ref == 'refs/heads/main' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

实战五:定时任务与手动触发

除了代码触发,Actions 还支持定时执行和手动触发:

name: Scheduled Tasks

on:
  schedule:
    # 每天凌晨2点执行
    - cron: '0 2 * * *'
  # 手动触发(workflow_dispatch)
  workflow_dispatch:
    inputs:
      environment:
        description: 'Target environment'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production

jobs:
  scheduled-job:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Run scheduled backup
        run: |
          echo "Running backup for ${{ github.event.inputs.environment || 'staging' }}"
          ./scripts/backup.sh

常见优化技巧

1. 使用缓存加速构建

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

2. 并行执行多个 Job

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - run: npm run lint
  
  test-unit:
    runs-on: ubuntu-latest
    steps:
      - run: npm run test:unit
  
  test-e2e:
    runs-on: ubuntu-latest
    steps:
      - run: npm run test:e2e
  
  # 汇总结果
  ci:
    needs: [lint, test-unit, test-e2e]
    runs-on: ubuntu-latest
    steps:
      - run: echo "All checks passed!"

3. 超时设置避免长时间占用

jobs:
  build:
    timeout-minutes: 10  # 10分钟超时
    runs-on: ubuntu-latest
    steps:
      - ...

总结

GitHub Actions 为开发者提供了强大而灵活的自动化能力。通过本文的实战案例,你应该能够:

  • 搭建基础的 CI 流水线实现自动化测试
  • 配置 CD 将代码自动部署到服务器
  • 实现多环境管理和灰度发布
  • 使用 Docker 构建并推送镜像
  • 利用缓存和并行优化构建速度

自动化部署不仅节省时间,更能确保部署的一致性和可靠性。建议从简单的流水线开始,逐步添加更多自动化环节,最终实现真正的”一键部署”。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容