【剪映小助手源码精讲】第39章:CI流程

第39章:CI/CD流程

39.1 CI/CD概述

持续集成(CI)和持续部署(CD)是现代软件开发的重要实践,它们通过自动化构建、测试和部署流程,提高了软件开发的效率和质量。剪映小助手采用GitHub Actions作为CI/CD平台,实现了完整的自动化流程。

39.2 GitHub Actions工作流架构

39.2.1 工作流文件结构

剪映小助手的CI/CD流程通过两个主要的工作流文件实现:

  1. dev.yml:开发环境工作流,处理main分支的push和pull_request事件
  2. release.yml:发布环境工作流,处理版本tag的推送事件

39.2.2 开发环境工作流(dev.yml)

开发环境工作流主要负责代码的持续集成和开发环境的部署:

yaml 复制代码
name: Docker Image CI Dev

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

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Install uv
      uses: astral-sh/setup-uv@v3
      with:
        version: "0.4.0"
    
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'
    
    - name: Install dependencies
      run: |
        uv sync
        uv add --dev pytest pytest-html pytest-json-report
    
    - name: List directory structure
      run: ls -R
    
    - name: Prepare production files
      run: |
        mkdir -p dist
        cp -r src dist/
        cp pyproject.toml dist/
        cp main.py dist/
        cp -r tests dist/
        cp requirements*.txt dist/ 2>/dev/null || true
        cp .env.example dist/ 2>/dev/null || true
        ls -la dist/
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Log in to Docker Hub
      if: github.event_name != 'pull_request'
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: gogoshine/capcut-mate
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=sha,prefix={{branch}}-
          type=raw,value=latest,enable={{is_default_branch}}
    
    - name: Validate tag format
      run: |
        echo "Tags to be applied: ${{ steps.meta.outputs.tags }}"
        echo "Labels to be applied: ${{ steps.meta.outputs.labels }}"
        # 验证标签格式
        for tag in ${{ steps.meta.outputs.tags }}; do
          echo "Validating tag: $tag"
          if [[ ! "$tag" =~ ^[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$ ]]; then
            echo "Invalid tag format: $tag"
            exit 1
          fi
        done
        echo "All tags are valid"
    
    - name: Build and push Docker image
      uses: docker/build-push-action@v5
      with:
        context: .
        push: ${{ github.event_name != 'pull_request' }}
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-from: type=gha,scope=dev
        cache-to: type=gha,mode=max

39.2.3 发布环境工作流(release.yml)

发布环境工作流主要负责生产环境的构建和部署:

yaml 复制代码
name: Docker Image CI

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Install uv
      uses: astral-sh/setup-uv@v3
      with:
        version: "0.4.0"
    
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'
    
    - name: Install dependencies
      run: |
        uv sync
        uv add --dev pytest pytest-html pytest-json-report
    
    - name: Prepare production files
      run: |
        mkdir -p dist
        cp -r src dist/
        cp pyproject.toml dist/
        cp main.py dist/
        cp -r tests dist/
        cp requirements*.txt dist/ 2>/dev/null || true
        cp .env.example dist/ 2>/dev/null || true
        ls -la dist/
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Log in to Docker Hub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: gogoshine/capcut-mate
        tags: |
          type=ref,event=tag
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=semver,pattern={{major}}
          type=raw,value=latest,enable={{is_default_branch}}
    
    - name: Validate tag format
      run: |
        echo "Tags to be applied: ${{ steps.meta.outputs.tags }}"
        echo "Labels to be applied: ${{ steps.meta.outputs.labels }}"
        # 验证标签格式
        for tag in ${{ steps.meta.outputs.tags }}; do
          echo "Validating tag: $tag"
          if [[ ! "$tag" =~ ^[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$ ]]; then
            echo "Invalid tag format: $tag"
            exit 1
          fi
        done
        echo "All tags are valid"
    
    - name: Build and push Docker image
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

39.3 工作流详细解析

39.3.1 触发条件配置

开发环境触发条件
yaml 复制代码
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  • push事件:当代码推送到main分支时触发
  • pull_request事件:当向main分支发起拉取请求时触发
  • 分支过滤:只监听main分支的变化
发布环境触发条件
yaml 复制代码
on:
  push:
    tags:
      - 'v*'
  • tag事件:当推送以'v'开头的tag时触发
  • 版本tag:通常用于版本发布,如v1.0.0、v2.1.0等
  • 精确匹配:只监听符合特定模式的tag

39.3.2 环境准备阶段

代码检出
yaml 复制代码
- name: Checkout code
  uses: actions/checkout@v4
  • 操作:检出当前触发工作流的代码
  • 版本:使用v4版本的checkout动作
  • 功能:获取完整的代码仓库,包括子模块
Python环境配置
yaml 复制代码
- name: Install uv
  uses: astral-sh/setup-uv@v3
  with:
    version: "0.4.0"

- name: Set up Python
  uses: actions/setup-python@v5
  with:
    python-version: '3.11'
  • uv安装:安装指定版本的uv包管理器
  • Python版本:使用Python 3.11版本
  • 环境隔离:确保构建环境的独立性和一致性
依赖安装
yaml 复制代码
- name: Install dependencies
  run: |
    uv sync
    uv add --dev pytest pytest-html pytest-json-report
  • 依赖同步:使用uv sync安装项目依赖
  • 测试工具:安装pytest及其相关插件,为自动化测试做准备
  • 开发依赖:--dev参数确保开发工具也被安装

39.3.3 生产文件准备

yaml 复制代码
- name: Prepare production files
  run: |
    mkdir -p dist
    cp -r src dist/
    cp pyproject.toml dist/
    cp main.py dist/
    cp -r tests dist/
    cp requirements*.txt dist/ 2>/dev/null || true
    cp .env.example dist/ 2>/dev/null || true
    ls -la dist/

文件准备过程:

  1. 创建dist目录:建立生产文件输出目录
  2. 复制源码:将src目录复制到dist
  3. 配置文件:复制pyproject.toml项目配置文件
  4. 主程序:复制main.py主程序文件
  5. 测试文件:复制tests目录,包含测试用例
  6. 依赖文件:尝试复制requirements文件(如果存在)
  7. 环境示例:复制.env.example环境变量示例文件
  8. 文件列表:显示dist目录的文件结构

39.3.4 Docker构建配置

Docker Buildx设置
yaml 复制代码
- name: Set up Docker Buildx
  uses: docker/setup-buildx-action@v3
  • Buildx功能:提供多平台构建能力
  • 缓存支持:支持构建缓存,提高构建效率
  • 版本:使用v3版本的setup-buildx-action
Docker Hub登录
yaml 复制代码
- name: Log in to Docker Hub
  if: github.event_name != 'pull_request'
  uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}
  • 条件执行:只在非pull_request事件时执行登录
  • 密钥管理:使用GitHub Secrets管理Docker Hub凭据
  • 安全考虑:避免在PR构建中暴露登录信息

39.3.5 镜像标签管理

元数据提取
yaml 复制代码
- name: Extract metadata
  id: meta
  uses: docker/metadata-action@v5
  with:
    images: gogoshine/capcut-mate
    tags: |
      type=ref,event=branch
      type=ref,event=pr
      type=sha,prefix={{branch}}-
      type=raw,value=latest,enable={{is_default_branch}}

开发环境标签策略:

  • 分支标签:使用分支名作为标签
  • PR标签:使用PR编号作为标签
  • SHA标签:使用提交SHA的前缀
  • 最新标签:为默认分支添加latest标签

发布环境标签策略:

yaml 复制代码
tags: |
  type=ref,event=tag
  type=semver,pattern={{version}}
  type=semver,pattern={{major}}.{{minor}}
  type=semver,pattern={{major}}
  type=raw,value=latest,enable={{is_default_branch}}
  • tag标签:使用完整的tag名称
  • 版本标签:使用语义化版本号
  • 主版本标签:使用主版本号
  • 次版本标签:使用主版本.次版本格式
标签格式验证
yaml 复制代码
- name: Validate tag format
  run: |
    echo "Tags to be applied: ${{ steps.meta.outputs.tags }}"
    echo "Labels to be applied: ${{ steps.meta.outputs.labels }}"
    # 验证标签格式
    for tag in ${{ steps.meta.outputs.tags }}; do
      echo "Validating tag: $tag"
      if [[ ! "$tag" =~ ^[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$ ]]; then
        echo "Invalid tag format: $tag"
        exit 1
      fi
    done
    echo "All tags are valid"
  • 格式验证:使用正则表达式验证标签格式
  • 错误处理:发现无效标签时终止构建
  • 输出信息:显示待应用的标签和标签信息

39.3.6 镜像构建与推送

yaml 复制代码
- name: Build and push Docker image
  uses: docker/build-push-action@v5
  with:
    context: .
    push: ${{ github.event_name != 'pull_request' }}
    tags: ${{ steps.meta.outputs.tags }}
    labels: ${{ steps.meta.outputs.labels }}
    cache-from: type=gha
    cache-to: type=gha,mode=max

构建参数说明:

  • 构建上下文:使用当前目录作为构建上下文
  • 推送条件:只在非PR事件时推送镜像
  • 标签应用:应用提取的元数据标签
  • 标签信息:应用提取的标签信息
  • 构建缓存:使用GitHub Actions缓存
  • 缓存模式:最大缓存模式,提高后续构建速度

39.4 自动化测试集成

39.4.1 测试框架配置

虽然工作流中安装了pytest,但可以在工作流中添加测试执行步骤:

yaml 复制代码
- name: Run tests
  run: |
    uv run pytest tests/ -v --html=reports/test_report.html --json-report --json-report-file=reports/test_report.json
  
- name: Upload test results
  uses: actions/upload-artifact@v4
  if: always()
  with:
    name: test-results
    path: reports/

39.4.2 测试报告生成

测试报告的配置:

  • HTML报告:生成可视化的HTML测试报告
  • JSON报告:生成结构化的JSON测试报告
  • 详细输出:使用-v参数显示详细测试输出
  • 结果上传:将测试报告作为构建产物上传

39.4.3 测试质量门禁

可以添加测试质量检查:

yaml 复制代码
- name: Check test coverage
  run: |
    uv run pytest tests/ --cov=src --cov-report=html --cov-report=json
    coverage_percentage=$(uv run coverage report --format=total | grep -o '[0-9]\+\.[0-9]\+' | head -1)
    echo "Test coverage: ${coverage_percentage}%"
    if (( $(echo "$coverage_percentage < 80" | bc -l) )); then
      echo "Test coverage is below 80%"
      exit 1
    fi

39.5 环境配置管理

39.5.1 密钥管理

GitHub Secrets的配置:

  • DOCKERHUB_USERNAME:Docker Hub用户名
  • DOCKERHUB_TOKEN:Docker Hub访问令牌
  • 配置位置:Settings -> Secrets and variables -> Actions
  • 安全考虑:密钥值不会显示在日志中

39.5.2 环境变量配置

环境变量的使用:

yaml 复制代码
env:
  PYTHON_VERSION: '3.11'
  UV_VERSION: '0.4.0'
  
- name: Set up Python
  uses: actions/setup-python@v5
  with:
    python-version: ${{ env.PYTHON_VERSION }}

39.5.3 条件执行

条件执行的使用:

yaml 复制代码
- name: Deploy to production
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  run: |
    echo "Deploying to production"

39.6 部署策略

39.6.1 蓝绿部署

蓝绿部署的实现思路:

  1. 准备两个相同的生产环境
  2. 新版本部署到绿色环境
  3. 验证绿色环境功能
  4. 切换流量到绿色环境
  5. 保留蓝色环境用于回滚

39.6.2 滚动部署

滚动部署的实现:

yaml 复制代码
- name: Rolling deployment
  run: |
    # 逐步替换实例
    docker service update --image gogoshine/capcut-mate:${{ github.sha }} capcut-service

39.6.3 金丝雀部署

金丝雀部署的步骤:

  1. 部署新版本到少量实例
  2. 监控新版本性能指标
  3. 逐步增加新版本实例
  4. 完全切换到新版本

39.7 监控与回滚

39.7.1 部署监控

部署监控的配置:

yaml 复制代码
- name: Monitor deployment
  run: |
    # 检查服务健康状态
    for i in {1..30}; do
      if curl -f http://localhost:60000/health; then
        echo "Service is healthy"
        exit 0
      fi
      sleep 10
    done
    echo "Service health check failed"
    exit 1

39.7.2 自动回滚

自动回滚机制:

yaml 复制代码
- name: Rollback on failure
  if: failure()
  run: |
    echo "Deployment failed, rolling back"
    # 执行回滚操作
    docker service rollback capcut-service

39.8 性能优化

39.8.1 构建缓存优化

缓存配置的最佳实践:

yaml 复制代码
cache-from: |
  type=gha
  type=registry,ref=gogoshine/capcut-mate:buildcache
cache-to: type=gha,mode=max

39.8.2 并行执行

并行执行的配置:

yaml 复制代码
strategy:
  matrix:
    python-version: ['3.10', '3.11', '3.12']
    
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.10', '3.11', '3.12']
    steps:
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}

39.8.3 构建时间优化

构建时间优化策略:

  1. 减少构建步骤:合并相关的构建步骤
  2. 使用缓存:充分利用各种缓存机制
  3. 优化镜像大小:使用更小的基础镜像
  4. 并行处理:尽可能并行执行独立的任务

39.9 安全考虑

39.9.1 密钥安全

密钥管理的最佳实践:

  • 使用GitHub Secrets:不要在代码中硬编码密钥
  • 定期轮换:定期更新访问密钥
  • 最小权限:为密钥分配最小必要的权限
  • 审计日志:监控密钥的使用情况

39.9.2 镜像安全

镜像安全检查:

yaml 复制代码
- name: Security scan
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: 'gogoshine/capcut-mate:${{ github.sha }}'
    format: 'sarif'
    output: 'trivy-results.sarif'

39.9.3 代码安全

代码安全扫描:

yaml 复制代码
- name: Code security scan
  uses: github/super-linter@v4
  env:
    DEFAULT_BRANCH: main
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

39.10 CI/CD最佳实践

39.10.1 分支策略

推荐的分支策略:

  1. 主分支保护:main分支需要PR才能修改
  2. 功能分支:每个功能开发使用独立分支
  3. 发布分支:发布版本使用专门的发布分支
  4. 热修复分支:紧急修复使用hotfix分支

39.10.2 提交信息规范

提交信息格式:

复制代码
type(scope): subject

body

footer

39.10.3 版本管理

版本管理策略:

  • 语义化版本:使用语义化版本号(MAJOR.MINOR.PATCH)
  • 自动版本:使用工具自动生成版本号
  • 变更日志:维护详细的变更日志
  • 发布说明:为每个版本编写发布说明

39.10.4 监控与告警

监控指标:

  • 构建成功率:监控构建成功的比例
  • 构建时间:监控构建耗时
  • 部署频率:监控部署的频率
  • 回滚次数:监控回滚的频率

通过合理的CI/CD流程设计和实施,剪映小助手实现了高效的自动化构建、测试和部署,大大提高了开发效率和软件质量。


附录

代码仓库地址:

  • GitHub: https://github.com/Hommy-master/capcut-mate
  • Gitee: https://gitee.com/taohongmin-gitee/capcut-mate

接口文档地址:

  • API文档地址: https://docs.jcaigc.cn
相关推荐
七夜zippoe6 小时前
Python并发与并行编程深度剖析:从GIL原理到高并发实战
服务器·网络·python·并发·gil
weixin_457340216 小时前
lora监督微调(SFT)
开发语言·python
weixin_390308466 小时前
Jenkins报Host key verification failed错误
python·jenkins
码农三叔6 小时前
(4-2-05)Python SDK仓库:MCP服务器端(5)Streamable HTTP传输+Streamable HTTP传输
开发语言·python·http·大模型·1024程序员节·mcp·mcp sdk
IT枫斗者6 小时前
Spring Boot 4.0 正式发布:新一代起点到底“新”在哪?(Spring Framework 7 / Java 25 / JSpecify / API 版本管理 / HTTP Service
java·开发语言·spring boot·后端·python·spring·http
AI大佬的小弟6 小时前
Python基础(10):Python函数基础详解
开发语言·python·函数·ai大模型基础·嵌套函数·变量的作用域·全局变量和局部变量
SZ1701102316 小时前
N-S图 (盒图) N-S图是“盒子嵌套”,PAD图是“树干分叉”*
python
智航GIS7 小时前
8.5 os 模块
python
njsgcs7 小时前
blender内部python调用 cats-blender-plugin 导入模型
python·blender