Skip to content

add ci for windows

add ci for windows #6

name: Cross-Platform Build
on:
pull_request:
branches: [ "main" ]
push:
branches: [ "main" ]
workflow_dispatch:
env:
BUILD_TYPE: Release
TEST_TYPE: CI_TEST
CLEAN_BUILD: false
jobs:
build:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
os: [macos-14, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
lfs: true
- name: Checkout LFS objects
run: git lfs checkout
# --- Caching Steps (Common) ---
- name: Cache Protobuf Build
if: env.CLEAN_BUILD != 'true'
id: protobuf-cache
uses: actions/cache@v3
with:
path: build/third_party/protobuf
key: ${{ runner.os }}-protobuf-build-${{ hashFiles('third_party/protobuf/version.json') }}
- name: Check Protobuf Cache
if: env.CLEAN_BUILD != 'true'
shell: bash
run: |
echo "Protobuf cache hit: ${{ steps.protobuf-cache.outputs.cache-hit }}"
if [ "${{ steps.protobuf-cache.outputs.cache-hit }}" != 'true' ]; then
echo "Protobuf cache missed or expired, setting CLEAN_BUILD to true."
echo "CLEAN_BUILD=true" >> $GITHUB_ENV
fi
- name: Cache JUCE Build
if: env.CLEAN_BUILD != 'true'
id: juce-cache
uses: actions/cache@v3
with:
path: build/third_party/JUCE
key: ${{ runner.os }}-juce-build-${{ hashFiles('third_party/JUCE/CMakeLists.txt') }}
- name: Check JUCE Cache
if: env.CLEAN_BUILD != 'true'
shell: bash
run: |
echo "JUCE cache hit: ${{ steps.juce-cache.outputs.cache-hit }}"
if [ "${{ steps.juce-cache.outputs.cache-hit }}" != 'true' ]; then
echo "JUCE cache missed or expired, setting CLEAN_BUILD to true."
echo "CLEAN_BUILD=true" >> $GITHUB_ENV
fi
- name: Cache IAMF Build
if: env.CLEAN_BUILD != 'true'
id: iamf-cache
uses: actions/cache@v3
with:
path: build/third_party/iamf
key: ${{ runner.os }}-iamf-build-${{ hashFiles('third_party/iamf/CMakeLists.txt') }}
- name: Check IAMF Cache
if: env.CLEAN_BUILD != 'true'
shell: bash
run: |
echo "IAMF cache hit: ${{ steps.iamf-cache.outputs.cache-hit }}"
if [ "${{ steps.iamf-cache.outputs.cache-hit }}" != 'true' ]; then
echo "IAMF cache missed or expired, setting CLEAN_BUILD to true."
echo "CLEAN_BUILD=true" >> $GITHUB_ENV
fi
- name: Cache Libear Build
if: env.CLEAN_BUILD != 'true'
id: libear-cache
uses: actions/cache@v3
with:
path: build/third_party/libear
key: ${{ runner.os }}-libear-build-${{ hashFiles('third_party/libear/CMakeLists.txt') }}
- name: Check Libear Cache
if: env.CLEAN_BUILD != 'true'
shell: bash
run: |
echo "Libear cache hit: ${{ steps.libear-cache.outputs.cache-hit }}"
if [ "${{ steps.libear-cache.outputs.cache-hit }}" != 'true' ]; then
echo "Libear cache missed or expired, setting CLEAN_BUILD to true."
echo "CLEAN_BUILD=true" >> $GITHUB_ENV
fi
- name: Cache Main Build
if: env.CLEAN_BUILD != 'true'
id: main-build-cache
uses: actions/cache@v3
with:
path: build
key: ${{ runner.os }}-main-build-${{ hashFiles('CMakeLists.txt', 'cmake/**', 'components/**/*.cpp', 'components/**/*.h') }}
- name: Check Main Build Cache
if: env.CLEAN_BUILD != 'true'
shell: bash
run: |
echo "Main build cache hit: ${{ steps.main-build-cache.outputs.cache-hit }}"
if [ "${{ steps.main-build-cache.outputs.cache-hit }}" != 'true' ]; then
echo "Main build cache missed or expired, setting CLEAN_BUILD to true."
echo "CLEAN_BUILD=true" >> $GITHUB_ENV
fi
- name: Check Clean Build
if: env.CLEAN_BUILD == 'true'
shell: bash
run: |
echo "CLEAN_BUILD is true, removing entire build directory."
if [ -d "build" ]; then rm -rf build; fi
# --- Formatting (macOS only for now) ---
- name: Check Formatting
if: runner.os == 'macOS'
run: |
brew install clang-format
find common -iname '*.h' -o -iname '*.cpp' | xargs clang-format --style=file:.clang-format --dry-run -Werror -i
find rendererplugin -iname '*.h' -o -iname '*.cpp' | xargs clang-format --style=file:.clang-format --dry-run -Werror -i
find audioelementplugin -iname '*.h' -o -iname '*.cpp' | xargs clang-format --style=file:.clang-format --dry-run -Werror -i
# --- CMake Setup ---
- name: Setup CMake
uses: jwlawson/actions-setup-cmake@v1
with:
cmake-version: "3.30.x"
- name: Verify CMake
shell: bash
run: |
cmake --version
which cmake
# --- Install Dependencies (Windows) ---
- name: Cache Intel OneAPI
id: cache-oneapi
if: runner.os == 'Windows'
uses: actions/cache@v3
with:
path: oneapi
key: ${{ runner.os }}-oneapi-mkl-2025.3.0
- name: Install Intel OneAPI MKL (Windows)
if: runner.os == 'Windows' && steps.cache-oneapi.outputs.cache-hit != 'true'
shell: powershell
run: |
# Download Intel OneAPI Base Toolkit (Offline Installer)
# We use the offline installer because the online installer URL is not stable/predictable.
# This is a large download (~2.5GB), but we cache the result so this only happens once.
$installerUrl = "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/1f18901e-877d-469d-a41a-a10f11b39336/intel-oneapi-base-toolkit-2025.3.0.372_offline.exe"
$installerPath = "$env:TEMP\intel-oneapi-base-toolkit-offline.exe"
Write-Host "Downloading Intel OneAPI Base Toolkit from $installerUrl..."
# Use curl.exe for faster download (Invoke-WebRequest can be slow due to progress bar)
# -L: Follow redirects
# -o: Output file
# --retry: Retry on transient errors
& curl.exe -L -o "$installerPath" "$installerUrl" --retry 5 --retry-delay 5
if (-not (Test-Path $installerPath)) {
Write-Error "Download failed: File not found at $installerPath"
exit 1
}
Write-Host "Installing Intel OneAPI Base Toolkit (MKL only)..."
# Install to a local directory within the workspace so it can be cached
$installDir = "$env:GITHUB_WORKSPACE\oneapi"
# Run installer silently with custom install directory
$proc = Start-Process -FilePath $installerPath -ArgumentList "-s -a --silent --eula accept --components intel.oneapi.win.mkl.devel -p=NEED_VS2022_INTEGRATION=0 --install-dir `"$installDir`"" -Wait -NoNewWindow -PassThru
if ($proc.ExitCode -ne 0) {
Write-Error "Installation failed with exit code $($proc.ExitCode)"
exit 1
}
Write-Host "Installation complete."
- name: Set MKLROOT Environment Variable
if: runner.os == 'Windows'
shell: powershell
run: |
$mklRoot = "$env:GITHUB_WORKSPACE\oneapi\mkl\latest"
if (Test-Path $mklRoot) {
Write-Host "MKL found at: $mklRoot"
echo "MKLROOT=$mklRoot" | Out-File -FilePath $env:GITHUB_ENV -Append
} else {
Write-Error "MKL installation failed or not found at expected path: $mklRoot"
exit 1
}
- name: Verify MKL install (Windows)
if: runner.os == 'Windows'
shell: powershell
run: |
Write-Host "MKLROOT is: $env:MKLROOT"
$libPath = "$env:MKLROOT\lib"
$lib64Path = "$env:MKLROOT\lib\intel64"
if (Test-Path $lib64Path) {
Write-Host "Found lib/intel64"
Get-ChildItem $lib64Path | Select-Object Name | Select-Object -First 5
} elseif (Test-Path $libPath) {
Write-Host "Found lib (root)"
Get-ChildItem $libPath | Select-Object Name | Select-Object -First 5
} else {
Write-Warning "Could not find lib or lib/intel64 under MKLROOT"
Get-ChildItem "$env:MKLROOT" -Recurse -Depth 2
}
# --- Configure (Windows) ---
- name: Configure CMake (Windows)
if: runner.os == 'Windows'
shell: powershell
run: |
cmake -S . -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
-D${{ env.TEST_TYPE }}=ON `
-DBUILD_TESTING=ON `
-DZMQ_BUILD_TESTS=OFF `
-DMKL_ROOT="$env:MKLROOT" `
-DVCPKG_TARGET_TRIPLET=x64-windows `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
# --- Configure (macOS) ---
- name: Configure CMake (macOS)
if: runner.os == 'macOS'
run: |
cmake -S . -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -G "Unix Makefiles" \
-D${{ env.TEST_TYPE }}=ON \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_COMPILER=clang \
-DBUILD_TESTING=ON \
-DZMQ_BUILD_TESTS=OFF
# --- Build ---
- name: Build
shell: bash
run: |
if [ "${{ runner.os }}" == "macOS" ]; then
# Limit parallelism on macOS to avoid "Resource temporarily unavailable" errors
cmake --build build --config ${{ env.BUILD_TYPE }} -j 4
else
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
fi
# --- Test ---
- name: Test
working-directory: ${{ github.workspace }}/build
shell: bash
run: ctest -C ${{ env.BUILD_TYPE }} --output-on-failure
# --- Logs ---
- name: Dump Test Logs
if: ${{ failure() }}
shell: bash
run: |
echo "//// CTest Logs ////"
if [ -f "Testing/Temporary/LastTest.log" ]; then cat Testing/Temporary/LastTest.log; fi
echo "//// Eclipsa Logs ////"
# Try to find logs in common locations
if [ -f "/tmp/Eclipsa_Audio_Plugin/log.txt" ]; then
cat /tmp/Eclipsa_Audio_Plugin/log.txt
elif [ -f "$TEMP/Eclipsa_Audio_Plugin/log.txt" ]; then
cat "$TEMP/Eclipsa_Audio_Plugin/log.txt"
else
echo "Log file not found."
fi