Skip to content

CI/CD Automation Infrastructure

Overview

Complete CI/CD automation for AudioLab using GitHub Actions. Builds, tests, and validates every commit across all platforms with comprehensive quality gates.

Philosophy: Automation converts good intentions into guarantees. This infrastructure ensures code quality without human intervention.


Directory Structure

03_06_ci_cd_automation/
├── 03_06_00_github_actions/      # Workflow definitions
├── 03_06_01_build_matrix/        # Platform build configurations
├── 03_06_02_test_automation/     # Test execution and reporting
├── 03_06_03_artifact_management/ # Build artifact handling
└── 03_06_04_quality_gates/       # Code quality enforcement

Quick Start

Local Testing

Before pushing, validate locally:

# Format check
clang-format --dry-run --Werror **/*.cpp **/*.hpp

# Build all configs
cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel

# Run tests
ctest --test-dir build --output-on-failure

# Run static analysis
cppcheck --enable=all "2 - FOUNDATION/04_CORE"

CI Workflows

Workflow Trigger Purpose Duration
ci.yml Push/PR to main/develop Full CI pipeline ~12-15 min
nightly.yml Daily at 2 AM UTC Extended testing ~30 min
release.yml Version tag push Build + publish release ~20 min
pr-validation.yml Pull request Quick validation ~8 min

Build Matrix

Platforms

Windows: - OS: Windows Server 2022 - Compiler: MSVC 2022 - Architectures: x64, ARM64 (planned) - Plugin Formats: VST3, AAX

macOS: - OS: macOS 13 (Ventura) - Compiler: Clang 15 - Architectures: x64, ARM64, Universal - Plugin Formats: VST3, AU, AAX

Linux: - OS: Ubuntu 22.04 LTS - Compiler: GCC 12 - Architectures: x64, ARM64 (planned) - Plugin Formats: VST3, LV2

Build Configurations

Config Optimizations Debug Info Sanitizers Use Case
Debug Off Full ASan, UBSan Development
Release Max None None Production
RelWithDebInfo Max Full None Profiling
RT-Safe Max Minimal TSan Realtime validation

Caching Strategy

Cache Layers

┌─────────────────────────────────────┐
│ Layer 1: vcpkg dependencies         │  ~500 MB, changes rarely
│   Key: vcpkg-{OS}-{vcpkg.json}      │  Hit rate: ~95%
├─────────────────────────────────────┤
│ Layer 2: ccache (Linux/macOS)       │  ~1 GB, changes often
│   Key: ccache-{OS}-{run_id}         │  Hit rate: ~80%
├─────────────────────────────────────┤
│ Layer 3: CMake build cache          │  ~200 MB, incremental
│   Key: cmake-{OS}-{config}-{sha}    │  Hit rate: ~60%
└─────────────────────────────────────┘

Total cache size: ~1.7 GB
Cache hit reduces CI time: 25 min → 12 min

Cache Keys

vcpkg:
  key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}
  restore-keys: vcpkg-${{ runner.os }}-

ccache:
  key: ccache-${{ runner.os }}-${{ github.run_id }}
  restore-keys: ccache-${{ runner.os }}-

cmake:
  key: cmake-${{ runner.os }}-${{ matrix.config }}-${{ github.sha }}
  restore-keys: cmake-${{ runner.os }}-${{ matrix.config }}-

Quality Gates

All PRs must pass these gates before merge:

1. Code Formatting ✅

Tool: clang-format Config: .clang-format Action: Fail if code not formatted

find . -name '*.cpp' -o -name '*.hpp' | \
  xargs clang-format --dry-run --Werror

2. Static Analysis ✅

Tools: clang-tidy, cppcheck Action: Warn on issues (don't fail yet)

clang-tidy --config-file=.clang-tidy **/*.cpp
cppcheck --enable=warning,performance --std=c++20 .

3. Unit Tests ✅

Framework: Catch2 Coverage: ≥70% (enforced) Action: Fail if any test fails

ctest --output-on-failure --timeout 300

4. Code Coverage ✅

Tool: gcovr Target: 70% minimum Upload: Codecov

gcovr --xml coverage.xml
codecov -f coverage.xml

5. Security Scan ✅

Tool: Trivy Action: Fail on HIGH/CRITICAL vulnerabilities

trivy fs --severity HIGH,CRITICAL .

Test Automation

Test Suites

Suite Regex Timeout Runs On
Smoke smoke_* 60s All commits
Unit test_* 300s All commits
Integration integration_* 600s PR, main, develop
Benchmark bench_* 600s Release, nightly
Stress stress_* 1800s Nightly only

Test Execution

# Unit tests (always)
- run: ctest -R test_ --output-on-failure

# Integration tests (PR/main)
- run: ctest -R integration_ --output-on-failure
  if: github.event_name == 'pull_request'

# Benchmarks (Release config only)
- run: ctest -R bench_ --output-on-failure
  if: matrix.config == 'Release'

Test Reporting

  • JUnit XML uploaded to GitHub
  • Coverage report uploaded to Codecov
  • Benchmark results stored as artifacts

Artifact Management

Artifact Types

artifacts/
├── binaries/
│   ├── audiolab-Windows-Release-{sha}.zip
│   ├── audiolab-macOS-Release-{sha}.tar.gz
│   └── audiolab-Linux-Release-{sha}.tar.gz
├── test-results/
│   ├── junit-Windows-Debug.xml
│   └── coverage-Linux-Debug.html
└── packages/
    ├── AudioLab-2.1.3-Setup-Windows-x64.exe
    ├── AudioLab-2.1.3-Setup-macOS-Universal.dmg
    └── AudioLab-2.1.3-Linux-x64.tar.gz

Retention Policy

Source Retention Reason
Pull Request 7 days Short-lived branches
Develop branch 14 days Active development
Main branch 30 days Stable history
Release tag 365 days Long-term support
Nightly build 7 days Testing only

Release Automation

Trigger

Push a version tag:

git tag -a v2.1.3 -m "Release 2.1.3"
git push origin v2.1.3

Workflow

Tag pushed (v2.1.3)
    ├─→ Create GitHub Release (draft)
    ├─→ Build Windows (signed)
    ├─→ Build macOS (signed + notarized)
    └─→ Build Linux
    ├─→ Upload artifacts to release
    ├─→ Generate SHA256 checksums
    ├─→ Publish release
    └─→ Notify Slack #audiolab-releases

Code Signing

Windows:

- name: Sign binaries
  run: |
    signtool sign /f cert.pfx /p ${{ secrets.CERT_PASSWORD }} \
      /tr http://timestamp.digicert.com \
      /td sha256 *.vst3 *.exe

macOS:

- name: Sign and notarize
  run: |
    codesign --deep --force --sign "${{ secrets.SIGNING_IDENTITY }}" *.vst3
    xcrun notarytool submit --wait *.dmg
    xcrun stapler staple *.dmg


Performance Targets

CI Time Budget

Phase Target Current
Checkout + Setup 2 min ✅ 1.5 min
Configure CMake 1 min ✅ 0.8 min
Build (cached) 5 min ✅ 4.2 min
Run Tests 3 min ✅ 2.8 min
Quality Gates 2 min ✅ 1.9 min
Upload Artifacts 1 min ✅ 0.7 min
Total (warm cache) 15 min 12 min

Optimization Techniques

  1. Parallel Builds

    run: cmake --build build --parallel $(nproc)
    

  2. ccache (Linux/macOS)

    - run: echo "/usr/lib/ccache" >> $GITHUB_PATH
    

  3. vcpkg Binary Caching

    env:
      VCPKG_BINARY_SOURCES: 'clear;x-gha,readwrite'
    

  4. Selective Testing

    # Skip slow tests on PR
    - run: ctest -E stress_ --output-on-failure
    


Notifications

Slack Integration

Channels: - #audiolab-ci - All CI activity - #audiolab-releases - Release announcements - #audiolab-alerts - Build failures

Webhook Setup:

# Add webhook URL as secret
gh secret set SLACK_WEBHOOK_URL --body "https://hooks.slack.com/services/..."

Notification Format:

{
  "text": "✅ AudioLab CI Passed",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Branch:* main\n*Commit:* a3f8b92\n*Author:* alice\n<link|View Run>"
      }
    }
  ]
}


Troubleshooting

Common Issues

Build Fails with "vcpkg not found":

# Ensure vcpkg is checked out
- uses: actions/checkout@v4
  with:
    submodules: recursive

Cache Miss on Every Run:

# Check hash key is stable
key: vcpkg-${{ hashFiles('vcpkg.json') }}  # ✅ Good
key: vcpkg-${{ github.sha }}               # ❌ Never hits

Tests Timeout:

# Increase timeout for slow tests
- run: ctest --timeout 600  # 10 minutes

Out of Disk Space:

# Clean before build
- run: docker system prune -af


Local CI Reproduction

Use act to run workflows locally:

# Install act
brew install act  # macOS
# or
choco install act  # Windows

# Run CI workflow
act -W .github/workflows/ci.yml

# Run specific job
act -j build-and-test -W .github/workflows/ci.yml

# With secrets
act --secret-file .secrets

Metrics & Monitoring

Track CI health:

Metric Target Alert If
Success Rate >95% <90%
Avg Duration <15 min >20 min
Cache Hit Rate >80% <60%
Queue Time <2 min >5 min
Flaky Test Rate <2% >5%

Dashboard: https://github.com/audiolab/audiolab/actions


Future Enhancements

  • Self-hosted runners for faster builds
  • Matrix testing across DAW versions
  • Automated performance regression detection
  • Gradual rollout (canary releases)
  • Auto-rollback on high crash rate

References


Remember: CI/CD is your safety net. Invest in making it fast, reliable, and comprehensive.