From 5abd66ca45da7a7dc5fa9373453c842ce47943d8 Mon Sep 17 00:00:00 2001 From: David Sisco Date: Mon, 14 Sep 2026 21:16:00 -0700 Subject: [PATCH 1/3] chore: split windows container build into stages for posterity --- containers/Dockerfile.windows-clang20 | 10 +++++++--- docs/ContainerValidation.md | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/containers/Dockerfile.windows-clang20 b/containers/Dockerfile.windows-clang20 index 30e9c84..18785e3 100644 --- a/containers/Dockerfile.windows-clang20 +++ b/containers/Dockerfile.windows-clang20 @@ -3,7 +3,7 @@ ARG WINDOWS_BASE=mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2022@sha256:3983348680840ca6e53ad641e314c3c9184ca2fd19f88bc467600f7d9f6e9d73 -FROM ${WINDOWS_BASE} +FROM ${WINDOWS_BASE} AS toolchain LABEL org.opencontainers.image.title="SimdLib Windows clang-cl 20 validation" ` org.opencontainers.image.description="Visual Studio 2022 Build Tools and pinned LLVM 20 environment for SimdLib" ` @@ -82,8 +82,12 @@ RUN clang-cl.exe --version; ` git.exe --version; ` if ($LASTEXITCODE -ne 0) { throw 'Git validation failed' }; ` if (-not (Test-Path 'C:\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe')) { throw 'Visual Studio Ninja is missing' }; ` - if (-not (Test-Path 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe')) { throw 'Visual Studio locator is missing' }; ` - git.exe config --global --add safe.directory C:/workspace + if (-not (Test-Path 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe')) { throw 'Visual Studio locator is missing' } + +# Keep the validation runtime separate from the reusable compiler environment. +FROM toolchain AS validation-runtime + +RUN git.exe config --global --add safe.directory C:/workspace WORKDIR C:\workspace ENTRYPOINT ["pwsh.exe", "-NoLogo", "-NoProfile"] diff --git a/docs/ContainerValidation.md b/docs/ContainerValidation.md index 2034b7a..e8ae5c2 100644 --- a/docs/ContainerValidation.md +++ b/docs/ContainerValidation.md @@ -9,6 +9,10 @@ The Windows clang-cl 20 compatibility cell is isolated separately in `containers/Dockerfile.windows-clang20`. That Windows Server Core image contains Visual Studio 2022 Build Tools, Chocolatey-provisioned LLVM 20.1.8, CMake 3.31.6, PowerShell 7.5.3, and MinGit. +Its named `toolchain` stage owns installation and verification of that compiler +environment. The final `validation-runtime` stage inherits the verified +toolchain and owns workspace trust, the runtime working-directory, and the +entrypoint contract. `tools/Run-WindowsClang20Container.ps1` runs the ordinary native `ClangCl` build, test, and benchmark commands inside it. It requires a Windows Docker engine; it is intentionally not part of the Linux Compose matrix. Visual From 54ef7c4820fb654607c20a66de82df9a9d4ee782 Mon Sep 17 00:00:00 2001 From: David Sisco Date: Mon, 14 Sep 2026 21:32:05 -0700 Subject: [PATCH 2/3] dev: implement windows container build image caching for github actions pipeline --- .github/workflows/ci.yml | 35 +++++++++++++++++++++++++++++++++-- docs/ContainerValidation.md | 11 +++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25ff5c2..3346561 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,39 @@ jobs: runs-on: windows-2022 steps: - uses: actions/checkout@v4 - - name: Build the Windows clang-cl 20 container and validation cell - run: tools/Run-WindowsClang20Container.ps1 -Action Build + - name: Restore compiler image archive + id: compiler-cache + uses: actions/cache/restore@v4 + with: + path: ${{ runner.temp }}/windows-clang20.tar + key: windows-2022-amd64-clang20-image-v1-${{ hashFiles('containers/Dockerfile.windows-clang20', '.dockerignore') }} + - name: Load cached compiler image + if: steps.compiler-cache.outputs.cache-hit == 'true' + shell: pwsh + run: | + docker load --input "$env:RUNNER_TEMP/windows-clang20.tar" + if ($LASTEXITCODE -ne 0) { throw 'Compiler image load failed' } + - name: Build and archive compiler image + if: steps.compiler-cache.outputs.cache-hit != 'true' + shell: pwsh + run: | + docker build --isolation=process --memory 4GB ` + --file containers/Dockerfile.windows-clang20 ` + --tag simdlib/windows-clang20:local . + if ($LASTEXITCODE -ne 0) { throw 'Compiler image build failed' } + + docker save --output "$env:RUNNER_TEMP/windows-clang20.tar" ` + simdlib/windows-clang20:local + if ($LASTEXITCODE -ne 0) { throw 'Compiler image archive failed' } + # Save before compilation so source failures do not discard the environment. + - name: Save compiler image archive + if: steps.compiler-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ runner.temp }}/windows-clang20.tar + key: ${{ steps.compiler-cache.outputs.cache-primary-key }} + - name: Build Windows clang-cl 20 validation cell + run: tools/Run-WindowsClang20Container.ps1 -Action Build -SkipImageBuild - name: Test the exact clang-cl 20 build receipt run: tools/Run-WindowsClang20Container.ps1 -Action Test -SkipImageBuild - name: Upload clang-cl 20 evidence diff --git a/docs/ContainerValidation.md b/docs/ContainerValidation.md index e8ae5c2..1dc441c 100644 --- a/docs/ContainerValidation.md +++ b/docs/ContainerValidation.md @@ -21,6 +21,17 @@ environment, while the standalone LLVM installation defines SimdLib's explicit clang-cl 20 compatibility floor. The image does not represent Visual Studio's default compiler selection or its optional bundled Clang version. +The Windows CI job caches the completed compiler image as a `docker save` +archive in GitHub Actions. An exact cache hit restores the archive with +`docker load`; a miss builds and saves the image before compiling SimdLib. +Both compilation and tests then use `-SkipImageBuild`. The cache key includes +the Windows Server 2022/amd64 environment, the Dockerfile and `.dockerignore` +hash, and an explicit `image-v1` revision. Source-only changes reuse the image; +changing these image inputs or incrementing the revision rebuilds it. Increment +the revision to refresh upstream installers/packages whose URLs have not changed. +No fallback cache keys are used. Archive restore/load performance and cache +storage requirements depend on the image size. + ## Environment contract | Service | Scope | Base | Compiler | From be9d831ac9e86709f897cea473842e6153390acb Mon Sep 17 00:00:00 2001 From: David Sisco Date: Mon, 14 Sep 2026 21:41:34 -0700 Subject: [PATCH 3/3] dev: standardize github actions naming for actions and tasks --- .github/workflows/ci.yml | 64 ++++++++++--------- .../workflows/container-reproducibility.yml | 11 ++-- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3346561..bbcd441 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: SimdLib CI +name: Validation on: push: @@ -12,15 +12,16 @@ permissions: jobs: native-msvc: - name: MSVC x64 validation + name: Windows | MSVC | Native runs-on: windows-2022 steps: - - uses: actions/checkout@v4 - - name: Build every MSVC validation cell + - name: Source | Check out repository + uses: actions/checkout@v4 + - name: Validation | Build targets run: tools/Build.ps1 -Scope Native -Compiler Msvc - - name: Test the exact MSVC build receipt + - name: Validation | Run tests run: tools/Run-Tests.ps1 -Scope Native -Compiler Msvc - - name: Upload MSVC evidence + - name: Evidence | Upload results if: always() uses: actions/upload-artifact@v4 with: @@ -38,23 +39,24 @@ jobs: if-no-files-found: error windows-clang20-container: - name: Windows clang-cl 20 container validation + name: Windows | clang-cl 20 | Container runs-on: windows-2022 steps: - - uses: actions/checkout@v4 - - name: Restore compiler image archive + - name: Source | Check out repository + uses: actions/checkout@v4 + - name: Image | Restore cached archive id: compiler-cache uses: actions/cache/restore@v4 with: path: ${{ runner.temp }}/windows-clang20.tar key: windows-2022-amd64-clang20-image-v1-${{ hashFiles('containers/Dockerfile.windows-clang20', '.dockerignore') }} - - name: Load cached compiler image + - name: Image | Load cached archive if: steps.compiler-cache.outputs.cache-hit == 'true' shell: pwsh run: | docker load --input "$env:RUNNER_TEMP/windows-clang20.tar" if ($LASTEXITCODE -ne 0) { throw 'Compiler image load failed' } - - name: Build and archive compiler image + - name: Image | Build and archive compiler environment if: steps.compiler-cache.outputs.cache-hit != 'true' shell: pwsh run: | @@ -67,17 +69,17 @@ jobs: simdlib/windows-clang20:local if ($LASTEXITCODE -ne 0) { throw 'Compiler image archive failed' } # Save before compilation so source failures do not discard the environment. - - name: Save compiler image archive + - name: Image | Save archive to cache if: steps.compiler-cache.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: ${{ runner.temp }}/windows-clang20.tar key: ${{ steps.compiler-cache.outputs.cache-primary-key }} - - name: Build Windows clang-cl 20 validation cell + - name: Validation | Build targets run: tools/Run-WindowsClang20Container.ps1 -Action Build -SkipImageBuild - - name: Test the exact clang-cl 20 build receipt + - name: Validation | Run tests run: tools/Run-WindowsClang20Container.ps1 -Action Test -SkipImageBuild - - name: Upload clang-cl 20 evidence + - name: Evidence | Upload results if: always() uses: actions/upload-artifact@v4 with: @@ -97,11 +99,12 @@ jobs: if-no-files-found: error native-clang22: - name: clang-cl 22 and Clang 22 coverage x64 validation + name: Windows | Clang 22 + coverage | Native runs-on: windows-2022 steps: - - uses: actions/checkout@v4 - - name: Install the pinned Windows toolchain with Chocolatey + - name: Source | Check out repository + uses: actions/checkout@v4 + - name: Toolchain | Install compiler environment shell: pwsh run: | choco upgrade cmake --version=4.4.0 --yes --allow-downgrade --no-progress --limit-output @@ -114,7 +117,7 @@ jobs: } 'C:\Program Files\CMake\bin' | Out-File -Encoding utf8 -Append $env:GITHUB_PATH 'C:\Program Files\LLVM\bin' | Out-File -Encoding utf8 -Append $env:GITHUB_PATH - - name: Verify the pinned Windows toolchain + - name: Toolchain | Verify compiler environment run: | $cmakeVersion = & 'C:\Program Files\CMake\bin\cmake.exe' --version | Select-Object -First 1 if ($cmakeVersion -ne 'cmake version 4.4.0') { throw "Unexpected CMake version: $cmakeVersion" } @@ -122,11 +125,11 @@ jobs: if ($version -notmatch 'clang version 22\.1\.7\b') { throw "Unexpected clang-cl version: $version" } $cmakeVersion $version - - name: Build every Clang 22 validation cell + - name: Validation | Build targets run: tools/Build.ps1 -Scope Native -Compiler ClangCl,ClangCoverage - - name: Test the exact Clang 22 build receipt + - name: Validation | Run tests run: tools/Run-Tests.ps1 -Scope Native -Compiler ClangCl,ClangCoverage - - name: Upload Clang 22 evidence + - name: Evidence | Upload results if: always() uses: actions/upload-artifact@v4 with: @@ -151,7 +154,7 @@ jobs: if-no-files-found: error container-compilers: - name: ${{ matrix.name }} container validation + name: Linux | ${{ matrix.name }} | Container runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -167,8 +170,9 @@ jobs: service: clang22 name: Clang 22 steps: - - uses: actions/checkout@v4 - - name: Install required Docker Compose + - name: Source | Check out repository + uses: actions/checkout@v4 + - name: Tools | Install Docker Compose shell: bash env: DOCKER_COMPOSE_VERSION: v2.39.0 @@ -187,9 +191,9 @@ jobs: test "${actual_sha256}" = "${expected_sha256}" chmod +x "${plugin_dir}/docker-compose" docker compose version - - name: Set up Docker Buildx + - name: Tools | Set up Buildx uses: docker/setup-buildx-action@v3 - - name: Build cached compiler image + - name: Image | Build compiler environment with cache uses: docker/build-push-action@v6 with: context: . @@ -200,13 +204,13 @@ jobs: # Include intermediate stages so the compiled CMake toolchain is reusable. cache-from: type=gha,version=2,scope=simdlib-${{ matrix.service }} cache-to: type=gha,version=2,scope=simdlib-${{ matrix.service }},mode=max,ignore-error=true - - name: Build selected Linux validation cells + - name: Validation | Build targets shell: pwsh run: tools/Build.ps1 -Scope Containers -Compiler ${{ matrix.compiler }} -SkipImageBuild - - name: Test the exact Linux build receipt + - name: Validation | Run tests shell: pwsh run: tools/Run-Tests.ps1 -Scope Containers -Compiler ${{ matrix.compiler }} - - name: Upload container evidence + - name: Evidence | Upload results if: always() uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/container-reproducibility.yml b/.github/workflows/container-reproducibility.yml index 1ddd3ea..4b14470 100644 --- a/.github/workflows/container-reproducibility.yml +++ b/.github/workflows/container-reproducibility.yml @@ -10,17 +10,18 @@ permissions: jobs: container-reproducibility: - name: Rebuild pinned images without cache + name: Linux | Compiler images | Reproducibility runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - name: Rebuild pinned environments without compiling the project + - name: Source | Check out repository + uses: actions/checkout@v4 + - name: Image | Rebuild compiler environments without cache shell: pwsh run: tools/Run-ContainerMatrix.ps1 -Action InspectEnvironment -NoImageCache - - name: Record image identities and sizes + - name: Evidence | Record image identities and sizes shell: pwsh run: docker image inspect simdlib/gcc13:local simdlib/gcc14:local simdlib/clang22:local | Out-File -Encoding utf8 out/pipeline/image-inspect.json - - name: Upload reproducibility evidence + - name: Evidence | Upload results if: always() uses: actions/upload-artifact@v4 with: