🚀 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¶
Option A: GitHub Actions (Recommended)¶
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:
After:
- name: Build
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release --parallel
3.3 Add Test Commands¶
Before:
After:
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:
4.3 Interpret Results¶
✅ Success:
❌ Failure:
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
⚠️ Troubleshooting¶
Issue 1: Pipeline Fails Immediately¶
Symptom:
Solutions: 1. Check runner is online (for self-hosted) 2. Verify runner labels match workflow 3. Check runner has capacity (not busy)
Verification:
Issue 2: Build Step Fails¶
Symptom:
Solution: Install dependencies on runner
For hosted runners:
For self-hosted runners: Run setup script or install manually.
Issue 3: Secrets Not Working¶
Symptom:
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:
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:
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:
Issue 6: macOS Code Signing Fails¶
Symptom:
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:
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:
📚 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¶
- GitHub Actions: Learn GitHub Actions
- CI/CD Best Practices: Martin Fowler - Continuous Integration
AudioLab-Specific¶
- PIPELINE_ARCHITECTURE.md - Architecture overview
- ../03_05_00_pipeline_templates/TEMPLATE_PHILOSOPHY.md - Template design
- ../03_05_01_runner_configuration/RUNNER_SETUP.md - Runner details
💡 Pro Tips¶
-
Start Simple: Get basic build working first, then add tests, then artifacts, etc.
-
Use Caching: Speed up builds significantly
-
Path Filters: Don't run CI on doc changes
-
Fail Fast: Don't waste time on obvious failures
-
Local Testing: Test workflows locally with act
🔗 Related Documents¶
- PIPELINE_ARCHITECTURE.md - Detailed architecture
- ../03_05_01_runner_configuration/RUNNER_SETUP.md - Runner configuration
- ../../03_07_security_infrastructure/03_07_01_secrets_management/ - Secrets management
✅ 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! 🎉