name: CI on: push: branches: - main - master - develop pull_request: schedule: # Nightly build at 14:00 UTC, roughly midnight in Australia/Sydney. - cron: "0 14 * * *" workflow_dispatch: jobs: native-windows: name: Native Windows Build And Tests runs-on: windows-2022 steps: - name: Manual Checkout With LFS Submodules shell: powershell env: GITEA_PAT: ${{ secrets.TOKEN }} run: | function Invoke-Git { & git @args if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } } function Add-GiteaTokenToUrl([string]$url) { if ([string]::IsNullOrWhiteSpace($env:GITEA_PAT)) { return $url } return $url -replace "^https://", "https://aiden:$($env:GITEA_PAT)@" } $serverUrl = "${{ gitea.server_url }}".TrimEnd("/") $repository = "${{ gitea.repository }}" if ([string]::IsNullOrWhiteSpace($serverUrl)) { $serverUrl = "https://git.f-40.com" } if ([string]::IsNullOrWhiteSpace($repository)) { $repository = "aiden/video-shader-toys" } $repoUrl = Add-GiteaTokenToUrl "$serverUrl/$repository.git" Invoke-Git init . Invoke-Git lfs install --local Invoke-Git remote add origin "$repoUrl" Invoke-Git fetch --depth=1 origin "${{ gitea.ref }}" Invoke-Git checkout FETCH_HEAD Invoke-Git lfs pull origin "${{ gitea.ref }}" Invoke-Git submodule sync --recursive $submoduleUrl = Invoke-Git config --file .gitmodules --get submodule.video-io-3rdParty.url $submoduleUrl = Add-GiteaTokenToUrl "$submoduleUrl" Invoke-Git config submodule.video-io-3rdParty.url "$submoduleUrl" Invoke-Git submodule update --init --recursive --depth=1 Invoke-Git -C video-io-3rdParty lfs pull Write-Host "Parent LFS files:" Invoke-Git lfs ls-files Write-Host "Submodule LFS files:" Invoke-Git -C video-io-3rdParty lfs ls-files - name: Verify Visual Studio ATL shell: powershell run: | $atlHeaders = @(Get-ChildItem -Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" -Filter atlbase.h -Recurse -ErrorAction SilentlyContinue) if ($atlHeaders.Count -eq 0) { Write-Error "Visual Studio Build Tools is missing ATL. Install the 'C++ ATL for latest v143 build tools (x86 & x64)' component, component ID Microsoft.VisualStudio.Component.VC.ATL, then restart the runner service." exit 1 } Write-Host "Found ATL header: $($atlHeaders[0].FullName)" - name: Configure Debug shell: powershell run: | $thirdPartyRoot = "${{ vars.THIRD_PARTY_ROOT }}" if ([string]::IsNullOrWhiteSpace($thirdPartyRoot)) { $thirdPartyRoot = $env:THIRD_PARTY_ROOT } if ([string]::IsNullOrWhiteSpace($thirdPartyRoot)) { $thirdPartyRoot = Join-Path $PWD "video-io-3rdParty" } if (-not (Test-Path -LiteralPath $thirdPartyRoot)) { $thirdPartyRoot = Join-Path $PWD "3rdParty" } $slangRoot = "${{ vars.SLANG_ROOT }}" if ([string]::IsNullOrWhiteSpace($slangRoot)) { $slangRoot = $env:SLANG_ROOT } if ([string]::IsNullOrWhiteSpace($slangRoot)) { $slangRoot = Join-Path $thirdPartyRoot "slang-2026.8-windows-x86_64" } $msdfAtlasGenRoot = "${{ vars.MSDF_ATLAS_GEN_ROOT }}" if ([string]::IsNullOrWhiteSpace($msdfAtlasGenRoot)) { $msdfAtlasGenRoot = $env:MSDF_ATLAS_GEN_ROOT } if ([string]::IsNullOrWhiteSpace($msdfAtlasGenRoot)) { $msdfAtlasGenRoot = Join-Path $thirdPartyRoot "msdf-atlas-gen" } $ndiSdkRoot = "${{ vars.NDI_SDK_ROOT }}" if ([string]::IsNullOrWhiteSpace($ndiSdkRoot)) { $ndiSdkRoot = $env:NDI_SDK_ROOT } if ([string]::IsNullOrWhiteSpace($ndiSdkRoot)) { $ndiSdkRoot = Join-Path $thirdPartyRoot "NDI 6 SDK" } $deckLinkSdkRoot = "${{ vars.DECKLINK_SDK_ROOT }}" if ([string]::IsNullOrWhiteSpace($deckLinkSdkRoot)) { $deckLinkSdkRoot = $env:DECKLINK_SDK_ROOT } if ([string]::IsNullOrWhiteSpace($deckLinkSdkRoot)) { $deckLinkSdkRoot = Join-Path $thirdPartyRoot "Blackmagic DeckLink SDK 16.0" } $requiredFiles = @( (Join-Path $slangRoot "bin\slangc.exe"), (Join-Path $slangRoot "bin\slang-compiler.dll"), (Join-Path $slangRoot "bin\slang-glslang.dll"), (Join-Path $slangRoot "LICENSE"), (Join-Path $msdfAtlasGenRoot "msdf-atlas-gen.exe"), (Join-Path $ndiSdkRoot "Include\Processing.NDI.Lib.h"), (Join-Path $ndiSdkRoot "Lib\x64\Processing.NDI.Lib.x64.lib"), (Join-Path $ndiSdkRoot "Bin\x64\Processing.NDI.Lib.x64.dll"), (Join-Path $deckLinkSdkRoot "Win\include\DeckLinkAPI.idl") ) $missingFiles = @($requiredFiles | Where-Object { -not (Test-Path -LiteralPath $_) }) if ($missingFiles.Count -gt 0) { Write-Error "Missing native third-party dependencies. Initialize the private video-io-3rdParty submodule, set THIRD_PARTY_ROOT, or configure per-SDK repository variables. Missing: $($missingFiles -join ', ')" exit 1 } Write-Host "Using THIRD_PARTY_ROOT=$thirdPartyRoot" Write-Host "Using SLANG_ROOT=$slangRoot" Write-Host "Using MSDF_ATLAS_GEN_ROOT=$msdfAtlasGenRoot" Write-Host "Using NDI_SDK_ROOT=$ndiSdkRoot" Write-Host "Using DECKLINK_SDK_ROOT=$deckLinkSdkRoot" cmake --preset vs2022-x64-debug -DTHIRD_PARTY_ROOT="$thirdPartyRoot" -DSLANG_ROOT="$slangRoot" -DMSDF_ATLAS_GEN_ROOT="$msdfAtlasGenRoot" -DNDI_SDK_ROOT="$ndiSdkRoot" -DDECKLINK_SDK_ROOT="$deckLinkSdkRoot" - name: Build Debug shell: powershell run: cmake --build --preset build-debug --parallel - name: Run Native Tests And Shader Validation shell: powershell run: cmake --build --preset build-debug --target RUN_TESTS --parallel ui-ubuntu: name: React UI Build runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install UI Dependencies working-directory: ui run: npm ci --no-audit --no-fund - name: Build UI working-directory: ui run: npm run build package-windows: name: Windows Release Package runs-on: windows-2022 if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' needs: - native-windows - ui-ubuntu steps: - name: Manual Checkout With LFS Submodules shell: powershell env: GITEA_PAT: ${{ secrets.TOKEN }} run: | function Invoke-Git { & git @args if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } } function Add-GiteaTokenToUrl([string]$url) { if ([string]::IsNullOrWhiteSpace($env:GITEA_PAT)) { return $url } return $url -replace "^https://", "https://aiden:$($env:GITEA_PAT)@" } $serverUrl = "${{ gitea.server_url }}".TrimEnd("/") $repository = "${{ gitea.repository }}" if ([string]::IsNullOrWhiteSpace($serverUrl)) { $serverUrl = "https://git.f-40.com" } if ([string]::IsNullOrWhiteSpace($repository)) { $repository = "aiden/video-shader-toys" } $repoUrl = Add-GiteaTokenToUrl "$serverUrl/$repository.git" Invoke-Git init . Invoke-Git lfs install --local Invoke-Git remote add origin "$repoUrl" Invoke-Git fetch --depth=1 origin "${{ gitea.ref }}" Invoke-Git checkout FETCH_HEAD Invoke-Git lfs pull origin "${{ gitea.ref }}" Invoke-Git submodule sync --recursive $submoduleUrl = Invoke-Git config --file .gitmodules --get submodule.video-io-3rdParty.url $submoduleUrl = Add-GiteaTokenToUrl "$submoduleUrl" Invoke-Git config submodule.video-io-3rdParty.url "$submoduleUrl" Invoke-Git submodule update --init --recursive --depth=1 Invoke-Git -C video-io-3rdParty lfs pull Write-Host "Parent LFS files:" Invoke-Git lfs ls-files Write-Host "Submodule LFS files:" Invoke-Git -C video-io-3rdParty lfs ls-files - name: Verify Visual Studio ATL shell: powershell run: | $atlHeaders = @(Get-ChildItem -Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" -Filter atlbase.h -Recurse -ErrorAction SilentlyContinue) if ($atlHeaders.Count -eq 0) { Write-Error "Visual Studio Build Tools is missing ATL. Install the 'C++ ATL for latest v143 build tools (x86 & x64)' component, component ID Microsoft.VisualStudio.Component.VC.ATL, then restart the runner service." exit 1 } Write-Host "Found ATL header: $($atlHeaders[0].FullName)" - name: Build UI shell: powershell working-directory: ui run: | npm ci --no-audit --no-fund npm run build - name: Configure Release shell: powershell run: | $thirdPartyRoot = "${{ vars.THIRD_PARTY_ROOT }}" if ([string]::IsNullOrWhiteSpace($thirdPartyRoot)) { $thirdPartyRoot = $env:THIRD_PARTY_ROOT } if ([string]::IsNullOrWhiteSpace($thirdPartyRoot)) { $thirdPartyRoot = Join-Path $PWD "video-io-3rdParty" } if (-not (Test-Path -LiteralPath $thirdPartyRoot)) { $thirdPartyRoot = Join-Path $PWD "3rdParty" } $slangRoot = "${{ vars.SLANG_ROOT }}" if ([string]::IsNullOrWhiteSpace($slangRoot)) { $slangRoot = $env:SLANG_ROOT } if ([string]::IsNullOrWhiteSpace($slangRoot)) { $slangRoot = Join-Path $thirdPartyRoot "slang-2026.8-windows-x86_64" } $msdfAtlasGenRoot = "${{ vars.MSDF_ATLAS_GEN_ROOT }}" if ([string]::IsNullOrWhiteSpace($msdfAtlasGenRoot)) { $msdfAtlasGenRoot = $env:MSDF_ATLAS_GEN_ROOT } if ([string]::IsNullOrWhiteSpace($msdfAtlasGenRoot)) { $msdfAtlasGenRoot = Join-Path $thirdPartyRoot "msdf-atlas-gen" } $ndiSdkRoot = "${{ vars.NDI_SDK_ROOT }}" if ([string]::IsNullOrWhiteSpace($ndiSdkRoot)) { $ndiSdkRoot = $env:NDI_SDK_ROOT } if ([string]::IsNullOrWhiteSpace($ndiSdkRoot)) { $ndiSdkRoot = Join-Path $thirdPartyRoot "NDI 6 SDK" } $deckLinkSdkRoot = "${{ vars.DECKLINK_SDK_ROOT }}" if ([string]::IsNullOrWhiteSpace($deckLinkSdkRoot)) { $deckLinkSdkRoot = $env:DECKLINK_SDK_ROOT } if ([string]::IsNullOrWhiteSpace($deckLinkSdkRoot)) { $deckLinkSdkRoot = Join-Path $thirdPartyRoot "Blackmagic DeckLink SDK 16.0" } $requiredFiles = @( (Join-Path $slangRoot "bin\slangc.exe"), (Join-Path $slangRoot "bin\slang-compiler.dll"), (Join-Path $slangRoot "bin\slang-glslang.dll"), (Join-Path $slangRoot "LICENSE"), (Join-Path $msdfAtlasGenRoot "msdf-atlas-gen.exe"), (Join-Path $ndiSdkRoot "Include\Processing.NDI.Lib.h"), (Join-Path $ndiSdkRoot "Lib\x64\Processing.NDI.Lib.x64.lib"), (Join-Path $ndiSdkRoot "Bin\x64\Processing.NDI.Lib.x64.dll"), (Join-Path $deckLinkSdkRoot "Win\include\DeckLinkAPI.idl") ) $missingFiles = @($requiredFiles | Where-Object { -not (Test-Path -LiteralPath $_) }) if ($missingFiles.Count -gt 0) { Write-Error "Missing native third-party dependencies. Initialize the private video-io-3rdParty submodule, set THIRD_PARTY_ROOT, or configure per-SDK repository variables. Missing: $($missingFiles -join ', ')" exit 1 } Write-Host "Using THIRD_PARTY_ROOT=$thirdPartyRoot" Write-Host "Using SLANG_ROOT=$slangRoot" Write-Host "Using MSDF_ATLAS_GEN_ROOT=$msdfAtlasGenRoot" Write-Host "Using NDI_SDK_ROOT=$ndiSdkRoot" Write-Host "Using DECKLINK_SDK_ROOT=$deckLinkSdkRoot" cmake --preset vs2022-x64-release -DTHIRD_PARTY_ROOT="$thirdPartyRoot" -DSLANG_ROOT="$slangRoot" -DMSDF_ATLAS_GEN_ROOT="$msdfAtlasGenRoot" -DNDI_SDK_ROOT="$ndiSdkRoot" -DDECKLINK_SDK_ROOT="$deckLinkSdkRoot" - name: Build Release shell: powershell run: cmake --build --preset build-release --parallel - name: Install Runtime Package shell: powershell run: cmake --install build/vs2022-x64-release --config Release --prefix dist/VideoShader - name: Zip Runtime Package shell: powershell run: Compress-Archive -Path dist/VideoShader/* -DestinationPath dist/VideoShader.zip -Force - name: Upload Runtime Package # Gitea/GHES-compatible runners do not support the v4 artifact backend yet. uses: actions/upload-artifact@v3 with: name: VideoShader-windows-release path: dist/VideoShader.zip