ci-cd-automation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CI/CD Automation

CI/CD自动化

Pipeline Architecture

流水线架构

┌─────────────────────────────────────────────────────────────┐
│                    CI/CD PIPELINE STAGES                     │
├─────────────────────────────────────────────────────────────┤
│  TRIGGER: [Push] [PR] [Tag] [Schedule] [Manual]             │
│                              ↓                               │
│  VALIDATE (< 5 min):                                         │
│  Lint → Compile Check → Asset Validation                    │
│                              ↓                               │
│  TEST (10-30 min):                                           │
│  Unit Tests → Integration → PlayMode Tests                  │
│                              ↓                               │
│  BUILD (Parallel):                                           │
│  [Windows] [Linux] [macOS] [WebGL] [Android] [iOS]         │
│                              ↓                               │
│  DEPLOY:                                                     │
│  [Dev auto] → [Staging gate] → [Prod approval]             │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                    CI/CD PIPELINE STAGES                     │
├─────────────────────────────────────────────────────────────┤
│  TRIGGER: [Push] [PR] [Tag] [Schedule] [Manual]             │
│                              ↓                               │
│  验证 (< 5 分钟):                                         │
│  代码检查 → 编译检查 → 资源验证                    │
│                              ↓                               │
│  测试 (10-30 分钟):                                           │
│  单元测试 → 集成测试 → 运行模式测试                  │
│                              ↓                               │
│  构建 (并行):                                           │
│  [Windows] [Linux] [macOS] [WebGL] [Android] [iOS]         │
│                              ↓                               │
│  部署:                                                     │
│  [自动部署至开发环境] → [预发布环境审核门] → [生产环境审批]             │
└─────────────────────────────────────────────────────────────┘

GitHub Actions for Unity

Unity的GitHub Actions

yaml
undefined
yaml
undefined

✅ Production-Ready: Unity CI/CD Pipeline

✅ Production-Ready: Unity CI/CD Pipeline

name: Unity Build Pipeline
on: push: branches: [main, develop] pull_request: branches: [main] workflow_dispatch: inputs: buildType: description: 'Build type' required: true default: 'development' type: choice options: - development - release
env: UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: lfs: true
  - uses: actions/cache@v3
    with:
      path: Library
      key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
      restore-keys: Library-

  - uses: game-ci/unity-test-runner@v4
    with:
      testMode: all
      artifactsPath: test-results
      checkName: Test Results

  - uses: actions/upload-artifact@v3
    if: always()
    with:
      name: Test Results
      path: test-results
build: needs: test runs-on: ubuntu-latest strategy: fail-fast: false matrix: targetPlatform: - StandaloneWindows64 - StandaloneLinux64 - WebGL steps: - uses: actions/checkout@v4 with: lfs: true
  - uses: actions/cache@v3
    with:
      path: Library
      key: Library-${{ matrix.targetPlatform }}-${{ hashFiles('Assets/**', 'Packages/**') }}

  - uses: game-ci/unity-builder@v4
    with:
      targetPlatform: ${{ matrix.targetPlatform }}
      versioning: Semantic
      buildMethod: BuildScript.PerformBuild

  - uses: actions/upload-artifact@v3
    with:
      name: Build-${{ matrix.targetPlatform }}
      path: build/${{ matrix.targetPlatform }}
      retention-days: 14
deploy-staging: needs: build if: github.ref == 'refs/heads/develop' runs-on: ubuntu-latest environment: staging steps: - uses: actions/download-artifact@v3 with: name: Build-WebGL path: build/
  - name: Deploy to Staging
    run: |
      # Deploy to staging server
      aws s3 sync build/ s3://game-staging-bucket/
undefined
name: Unity Build Pipeline
on: push: branches: [main, develop] pull_request: branches: [main] workflow_dispatch: inputs: buildType: description: 'Build type' required: true default: 'development' type: choice options: - development - release
env: UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: lfs: true
  - uses: actions/cache@v3
    with:
      path: Library
      key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
      restore-keys: Library-

  - uses: game-ci/unity-test-runner@v4
    with:
      testMode: all
      artifactsPath: test-results
      checkName: Test Results

  - uses: actions/upload-artifact@v3
    if: always()
    with:
      name: Test Results
      path: test-results
build: needs: test runs-on: ubuntu-latest strategy: fail-fast: false matrix: targetPlatform: - StandaloneWindows64 - StandaloneLinux64 - WebGL steps: - uses: actions/checkout@v4 with: lfs: true
  - uses: actions/cache@v3
    with:
      path: Library
      key: Library-${{ matrix.targetPlatform }}-${{ hashFiles('Assets/**', 'Packages/**') }}

  - uses: game-ci/unity-builder@v4
    with:
      targetPlatform: ${{ matrix.targetPlatform }}
      versioning: Semantic
      buildMethod: BuildScript.PerformBuild

  - uses: actions/upload-artifact@v3
    with:
      name: Build-${{ matrix.targetPlatform }}
      path: build/${{ matrix.targetPlatform }}
      retention-days: 14
deploy-staging: needs: build if: github.ref == 'refs/heads/develop' runs-on: ubuntu-latest environment: staging steps: - uses: actions/download-artifact@v3 with: name: Build-WebGL path: build/
  - name: Deploy to Staging
    run: |
      # Deploy to staging server
      aws s3 sync build/ s3://game-staging-bucket/
undefined

Unreal Engine Pipeline

Unreal Engine流水线

yaml
undefined
yaml
undefined

✅ Production-Ready: Unreal CI/CD

✅ Production-Ready: Unreal CI/CD

name: Unreal Build Pipeline
on: push: branches: [main]
jobs: build: runs-on: [self-hosted, unreal] steps: - uses: actions/checkout@v4 with: lfs: true
  - name: Build Development
    run: |
      & "$env:UE_ROOT/Engine/Build/BatchFiles/RunUAT.bat" `
        BuildCookRun `
        -project="${{ github.workspace }}/MyGame.uproject" `
        -platform=Win64 `
        -clientconfig=Development `
        -build -cook -stage -pak -archive `
        -archivedirectory="${{ github.workspace }}/Build"

  - uses: actions/upload-artifact@v3
    with:
      name: UnrealBuild-Win64
      path: Build/
undefined
name: Unreal Build Pipeline
on: push: branches: [main]
jobs: build: runs-on: [self-hosted, unreal] steps: - uses: actions/checkout@v4 with: lfs: true
  - name: Build Development
    run: |
      & "$env:UE_ROOT/Engine/Build/BatchFiles/RunUAT.bat" `
        BuildCookRun `
        -project="${{ github.workspace }}/MyGame.uproject" `
        -platform=Win64 `
        -clientconfig=Development `
        -build -cook -stage -pak -archive `
        -archivedirectory="${{ github.workspace }}/Build"

  - uses: actions/upload-artifact@v3
    with:
      name: UnrealBuild-Win64
      path: Build/
undefined

Build Optimization

构建优化

BUILD TIME OPTIMIZATION:
┌─────────────────────────────────────────────────────────────┐
│  STRATEGY              │ TIME SAVINGS │ EFFORT            │
├────────────────────────┼──────────────┼───────────────────┤
│  Library caching       │ 30-50%       │ Low               │
│  Parallel builds       │ 40-60%       │ Low               │
│  Self-hosted runners   │ 20-40%       │ Medium            │
│  Incremental builds    │ 50-80%       │ Medium            │
│  Asset bundles split   │ 30-50%       │ High              │
└─────────────────────────────────────────────────────────────┘
构建时间优化:
┌─────────────────────────────────────────────────────────────┐
│  策略              │ 时间节省占比 │ 实施难度            │
├────────────────────────┼──────────────┼───────────────────┤
│  库缓存               │ 30-50%       │ 低               │
│  并行构建             │ 40-60%       │ 低               │
│  自托管运行器         │ 20-40%       │ 中            │
│  增量构建             │ 50-80%       │ 中            │
│  资源包拆分           │ 30-50%       │ 高              │
└─────────────────────────────────────────────────────────────┘

Automated Testing

自动化测试

csharp
// ✅ Production-Ready: PlayMode Test
[TestFixture]
public class PlayerMovementTests
{
    private GameObject _player;
    private PlayerController _controller;

    [UnitySetUp]
    public IEnumerator SetUp()
    {
        var prefab = Resources.Load<GameObject>("Prefabs/Player");
        _player = Object.Instantiate(prefab);
        _controller = _player.GetComponent<PlayerController>();
        yield return null;
    }

    [UnityTest]
    public IEnumerator Player_MovesForward_WhenInputApplied()
    {
        var startPos = _player.transform.position;

        _controller.SetInput(Vector2.up);
        yield return new WaitForSeconds(0.5f);

        Assert.Greater(_player.transform.position.z, startPos.z);
    }

    [UnityTearDown]
    public IEnumerator TearDown()
    {
        Object.Destroy(_player);
        yield return null;
    }
}
csharp
// ✅ Production-Ready: PlayMode Test
[TestFixture]
public class PlayerMovementTests
{
    private GameObject _player;
    private PlayerController _controller;

    [UnitySetUp]
    public IEnumerator SetUp()
    {
        var prefab = Resources.Load<GameObject>("Prefabs/Player");
        _player = Object.Instantiate(prefab);
        _controller = _player.GetComponent<PlayerController>();
        yield return null;
    }

    [UnityTest]
    public IEnumerator Player_MovesForward_WhenInputApplied()
    {
        var startPos = _player.transform.position;

        _controller.SetInput(Vector2.up);
        yield return new WaitForSeconds(0.5f);

        Assert.Greater(_player.transform.position.z, startPos.z);
    }

    [UnityTearDown]
    public IEnumerator TearDown()
    {
        Object.Destroy(_player);
        yield return null;
    }
}

🔧 Troubleshooting

🔧 故障排查

┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Build times too long (>30 min)                     │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS:                                                   │
│ → Enable Library folder caching                             │
│ → Use self-hosted runners with SSDs                         │
│ → Parallelize platform builds                               │
│ → Split large asset bundles                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Flaky tests causing failures                       │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS:                                                   │
│ → Use test timeouts                                         │
│ → Isolate tests properly                                    │
│ → Add retry logic for network tests                         │
│ → Quarantine unstable tests                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Cache not restoring correctly                      │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS:                                                   │
│ → Check cache key hash inputs                               │
│ → Verify cache path is correct                              │
│ → Use restore-keys for partial matches                      │
│ → Check cache size limits                                   │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 问题:构建时间过长(>30分钟)                     │
├─────────────────────────────────────────────────────────────┤
│ 解决方案:                                                   │
│ → 启用Library文件夹缓存                             │
│ → 使用配备SSD的自托管运行器                         │
│ → 并行化多平台构建                               │
│ → 拆分大型资源包                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 问题:不稳定测试导致流水线失败                       │
├─────────────────────────────────────────────────────────────┤
│ 解决方案:                                                   │
│ → 为测试设置超时时间                                         │
│ → 确保测试完全隔离                                    │
│ → 为网络测试添加重试逻辑                         │
│ → 隔离不稳定测试                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 问题:缓存无法正确恢复                      │
├─────────────────────────────────────────────────────────────┤
│ 解决方案:                                                   │
│ → 检查缓存密钥的哈希输入                               │
│ → 验证缓存路径是否正确                              │
│ → 使用restore-keys实现部分匹配缓存                      │
│ → 检查缓存大小限制                                   │
└─────────────────────────────────────────────────────────────┘

Deployment Strategies

部署策略

StrategyRollback TimeRiskBest For
Blue-GreenInstantLowWeb builds
CanaryMinutesLowMobile apps
RollingMinutesMediumGame servers
Big BangHoursHighConsole releases

Use this skill: When setting up build pipelines, automating testing, or improving team workflows.
策略回滚时间风险适用场景
蓝绿部署即时Web构建
金丝雀部署数分钟移动应用
滚动部署数分钟游戏服务器
全量部署数小时主机游戏发布

使用场景:搭建构建流水线、实现测试自动化或优化团队工作流时。