Skip to content

🚀 CI/CD Setup Guide - From Zero to Hero

📋 Prerequisites

Before starting, ensure you have:

  • GitHub/GitLab account with admin access
  • Repository created and cloned locally
  • Admin access to repository settings
  • Code signing certificates (for production)
  • Access to secrets/credentials
  • Understanding of git basics

System Requirements

For Self-Hosted Runners: - Windows: Windows 10+ / Server 2019+ - macOS: macOS 11+ (Big Sur) - Linux: Ubuntu 20.04+ / equivalent - 2+ CPU cores - 4GB+ RAM - 50GB+ disk space

🔧 Step-by-Step Setup

Part 1: Choose Your Platform

Advantages: - No installation needed (built into GitHub) - Just add .github/workflows/*.yml files - Free for public repos - Easy to get started

Setup:

# 1. Create workflows directory
mkdir -p .github/workflows

# 2. Copy template
cp 2\ -\ FOUNDATION/03_INFRA/03_06_ci_cd_automation/03_05_00_pipeline_templates/github_workflows_template.yml \
   .github/workflows/ci.yml

# 3. Customize (see below)

Option B: Self-Hosted Runner (For Audio Hardware Testing)

When to use: - Need real audio hardware access - Need GPU acceleration - Want to save on macOS minutes - Need specific software pre-installed

Setup:

Windows:

# Navigate to runner setup directory
cd "2 - FOUNDATION\03_INFRA\03_06_ci_cd_automation\03_05_01_runner_configuration"

# Run setup script
.\runner_setup.ps1 `
    -RepoUrl "https://github.com/your-org/audio-lab" `
    -Token "YOUR_GITHUB_TOKEN"

Linux/macOS:

cd "2 - FOUNDATION/03_INFRA/03_06_ci_cd_automation/03_05_01_runner_configuration"

chmod +x runner_setup.sh
./runner_setup.sh \
    --repo-url "https://github.com/your-org/audio-lab" \
    --token "YOUR_GITHUB_TOKEN"

Get Token: 1. Go to repo → Settings → Actions → Runners 2. Click "New self-hosted runner" 3. Copy the token shown

Option C: GitLab CI

# 1. Copy template
cp 2\ -\ FOUNDATION/03_INFRA/03_06_ci_cd_automation/03_05_00_pipeline_templates/gitlab_ci_template.yml \
   .gitlab-ci.yml

# 2. Customize variables
# 3. Push to GitLab

Part 2: Configure Secrets

Secrets store sensitive data like passwords, API keys, certificates.

GitHub UI Method

Step-by-step: 1. Navigate to repo on GitHub 2. Settings → Secrets and variables → Actions 3. Click "New repository secret" 4. Add each secret:

Required Secrets:

Name Description How to Get
WINDOWS_CERT_PASSWORD Code signing cert password From cert provider
APPLE_ID Apple Developer email Apple Developer account
APPLE_APP_PASSWORD App-specific password appleid.apple.com → Security
APPLE_TEAM_ID Team ID Apple Developer portal
LICENSE_SERVER_API_KEY License validation key Admin panel
GITHUB_TOKEN For releases Auto-provided by GitHub

Optional Secrets:

Name Description
SLACK_WEBHOOK For Slack notifications
SENTRY_DSN For crash reporting
AWS_ACCESS_KEY_ID For S3 artifact storage
AWS_SECRET_ACCESS_KEY S3 secret key

Command-Line Method (GitHub CLI)

# Install GitHub CLI
# Windows: choco install gh
# macOS: brew install gh
# Linux: See https://cli.github.com

# Authenticate
gh auth login

# Add secrets
gh secret set WINDOWS_CERT_PASSWORD --body "your_password_here"
gh secret set APPLE_ID --body "dev@example.com"
gh secret set LICENSE_SERVER_API_KEY --body "key_here"

# Verify
gh secret list

Part 3: Customize Pipeline

3.1 Edit Workflow File

Open .github/workflows/ci.yml and replace placeholders:

Before (Template):

name: CI Pipeline Template

on:
  push:
    branches: [ $DEFAULT_BRANCH ]

env:
  BUILD_TYPE: $BUILD_TYPE
  CMAKE_VERSION: $CMAKE_VERSION

jobs:
  build:
    runs-on: $RUNNER_OS

After (Customized):

name: AudioLab CI Pipeline

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

env:
  BUILD_TYPE: Release
  CMAKE_VERSION: 3.28

jobs:
  build:
    runs-on: ubuntu-latest

3.2 Add Build Commands

Replace placeholder commands with actual build logic:

Before:

- name: Build
  run: echo "Build commands here"

After:

- name: Build
  run: |
    cmake -B build -DCMAKE_BUILD_TYPE=Release
    cmake --build build --config Release --parallel

3.3 Add Test Commands

Before:

- name: Test
  run: echo "Test commands here"

After:

- name: Test
  run: |
    cd build
    ctest --output-on-failure --parallel 4

3.4 Configure Artifacts

Before:

- name: Upload Artifacts
  uses: actions/upload-artifact@v3
  with:
    name: $ARTIFACT_NAME
    path: $ARTIFACT_PATH

After:

- name: Upload Artifacts
  uses: actions/upload-artifact@v3
  with:
    name: audiolab-vst3-ubuntu
    path: |
      build/**/*.vst3
      build/**/*.so

Part 4: First Run

4.1 Commit and Push

# Add workflow file
git add .github/workflows/ci.yml

# Commit
git commit -m "Add CI/CD pipeline"

# Push to trigger
git push origin main

4.2 Monitor Execution

GitHub Actions: 1. Go to repo on GitHub 2. Click "Actions" tab 3. Click on your commit/workflow run 4. Watch live logs

URL format:

https://github.com/your-org/audio-lab/actions

4.3 Interpret Results

✅ Success:

Build (3m 42s)    ✓
Test (1m 15s)     ✓
Upload Artifacts  ✓

❌ Failure:

Build (2m 10s)    ✓
Test (0m 30s)     ✗  ← Failed here

Click on failed step to see error logs.

Part 5: Validation Checklist

  • Pipeline runs successfully
  • All tests pass
  • Artifacts generated and downloadable
  • Notifications received (if configured)
  • Branch protection rules active
  • Secrets not exposed in logs
  • Build time acceptable (< 15 min for PR)

Part 6: Enable Branch Protection

Prevent direct pushes to main without CI passing.

GitHub: 1. Settings → Branches 2. Add rule for main 3. Enable: - [ ] Require status checks to pass - [ ] Require branches to be up to date - [ ] Select your CI job (e.g., "build") - [ ] Require pull request reviews

# Example: Require CI to pass
required_status_checks:
  - build
  - test

⚠️ Troubleshooting

Issue 1: Pipeline Fails Immediately

Symptom:

Error: No runners available

Solutions: 1. Check runner is online (for self-hosted) 2. Verify runner labels match workflow 3. Check runner has capacity (not busy)

Verification:

# Check runner status
Settings  Actions  Runners

# Should show: ✓ Idle (green dot)

Issue 2: Build Step Fails

Symptom:

Error: cmake: command not found

Solution: Install dependencies on runner

For hosted runners:

- name: Setup Dependencies
  run: |
    sudo apt-get update
    sudo apt-get install -y cmake build-essential

For self-hosted runners: Run setup script or install manually.

Issue 3: Secrets Not Working

Symptom:

Error: WINDOWS_CERT_PASSWORD is not set

Solutions: 1. Verify secret name matches EXACTLY (case-sensitive) 2. Check secret is set at repo level (not org level) 3. Ensure workflow has permission to access secrets

Verification:

gh secret list  # Should show all secrets

Issue 4: Tests Fail on CI But Pass Locally

Common causes: - Different dependencies: CI has older/newer version - Race conditions: Multi-core CI exposes timing bugs - File paths: Absolute vs relative paths - Environment variables: Missing on CI

Solutions:

# 1. Pin dependencies
- name: Install Dependencies
  run: |
    pip install -r requirements.txt  # Pinned versions

# 2. Verbose test output
- name: Test
  run: ctest --verbose --output-on-failure

# 3. Upload test logs
- name: Upload Logs
  if: failure()
  uses: actions/upload-artifact@v3
  with:
    name: test-logs
    path: build/Testing/Temporary/

Issue 5: Artifact Upload Fails

Symptom:

Error: No files were found with the provided path: build/*.vst3

Solutions: 1. Verify build actually produces artifacts 2. Check path is correct (relative to repo root) 3. Use if-no-files-found: error to catch early

Debug:

- name: Debug - List Files
  run: |
    ls -R build/
    find build -name "*.vst3"

Issue 6: macOS Code Signing Fails

Symptom:

Error: No identity found for code signing

Solution: Add certificate to runner keychain

- name: Import Certificate
  env:
    CERTIFICATE_BASE64: ${{ secrets.MACOS_CERT_BASE64 }}
    CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERT_PASSWORD }}
  run: |
    echo $CERTIFICATE_BASE64 | base64 --decode > certificate.p12
    security create-keychain -p actions temp.keychain
    security import certificate.p12 -k temp.keychain -P $CERTIFICATE_PASSWORD -T /usr/bin/codesign
    security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k actions temp.keychain

Issue 7: Runner Out of Disk Space

Symptom:

Error: No space left on device

Solutions:

# Add cleanup step
- name: Free Disk Space
  run: |
    sudo rm -rf /usr/share/dotnet
    sudo rm -rf /opt/ghc
    sudo apt-get clean
    docker system prune -af

For self-hosted runners:

# Clean workspace
rm -rf /path/to/runner/_work/*

# Or configure auto-cleanup

📚 Next Steps

After basic CI/CD is working:

1. Add Multi-Platform Builds

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-13, windows-2022]
    runs-on: ${{ matrix.os }}

2. Add Code Coverage

- name: Generate Coverage
  run: |
    cmake --build build --target coverage
    lcov --capture --directory . --output-file coverage.info

- name: Upload Coverage
  uses: codecov/codecov-action@v3
  with:
    files: coverage.info

3. Add Static Analysis

- name: Run Clang-Tidy
  run: |
    clang-tidy src/**/*.cpp -- -std=c++17

- name: Run Cppcheck
  run: cppcheck --enable=all --error-exitcode=1 src/

4. Add Deployment

- name: Deploy to CDN
  if: startsWith(github.ref, 'refs/tags/v')
  run: |
    aws s3 sync build/installers/ s3://audiolab-releases/

5. Add Notifications

- name: Slack Notification
  if: always()
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    webhook_url: ${{ secrets.SLACK_WEBHOOK }}

🎓 Learning Resources

Official Docs

Tutorials

AudioLab-Specific

💡 Pro Tips

  1. Start Simple: Get basic build working first, then add tests, then artifacts, etc.

  2. Use Caching: Speed up builds significantly

    - uses: actions/cache@v3
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
    

  3. Path Filters: Don't run CI on doc changes

    on:
      push:
        paths-ignore:
          - '**.md'
          - 'docs/**'
    

  4. Fail Fast: Don't waste time on obvious failures

    strategy:
      fail-fast: true
    

  5. Local Testing: Test workflows locally with act

    act push  # Simulate push event locally
    

✅ Success Checklist

You've successfully set up CI/CD when:

  • Push to branch triggers automatic build
  • All tests run and pass
  • Artifacts are generated
  • Failed builds notify you
  • PRs show build status
  • Main branch is protected (requires passing CI)
  • Build time is acceptable (< 15 min)
  • Team understands how to use it

Congratulations! Your CI/CD pipeline is now operational! 🎉