Skip to content

Fix chroma artifacts (issue #44 root cause): restrict green-diff deco… #243

Fix chroma artifacts (issue #44 root cause): restrict green-diff deco…

Fix chroma artifacts (issue #44 root cause): restrict green-diff deco… #243

Workflow file for this run

name: CI
on:
push:
pull_request:
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
quality:
name: Python quality
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- run: python -m pip install ruff mypy numpy pillow zstandard
- run: python -m ruff check wimf tests benchmarks examples setup.py --output-format=github
- run: python -m ruff format wimf tests benchmarks examples setup.py --check
- run: python -m mypy wimf --ignore-missing-imports --no-strict-optional --python-version 3.12
test:
name: ${{ matrix.os }} / Python ${{ matrix.python }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
python: "3.10"
- os: ubuntu-latest
python: "3.12"
- os: ubuntu-latest
python: "3.14"
- os: windows-latest
python: "3.12"
- os: macos-latest
python: "3.12"
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python }}
cache: pip
- run: python -m pip install --upgrade pip
- run: python -m pip install pytest pybind11 numpy pillow zstandard setuptools wheel
- run: python setup.py build_ext --inplace
- name: Verify native extensions
run: python -c "import wimf.wimf_cpp, wimf.wimf_v2_cpp; assert wimf.runtime_info()['native']"
- run: python -m pytest wimf/test_core.py wimf/test_v2.py wimf/test_features.py wimf/test_studio.py wimf/test_conformance.py wimf/test_extension_conformance.py wimf/test_pillow_plugin.py wimf/test_transport.py tests/test_integration_assets.py -v --junitxml=test-results.xml
- name: Upload test results
if: ${{ always() && hashFiles('test-results.xml') != '' }}
uses: actions/upload-artifact@v7
with:
name: test-results-${{ matrix.os }}-py${{ matrix.python }}
path: |
test-results.xml
tests/conformance/*.json
retention-days: 14
legacy-decode:
name: Legacy decode compatibility
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip
- run: python -m pip install pytest pybind11 numpy pillow zstandard setuptools wheel
- run: python setup.py build_ext --inplace
- name: Run legacy compatibility and warning tests
run: python -m pytest wimf/test_awif.py wimf/test_deprecations.py -v --junitxml=legacy-results.xml
- name: Upload legacy test results
if: ${{ always() && hashFiles('legacy-results.xml') != '' }}
uses: actions/upload-artifact@v7
with:
name: legacy-results
path: legacy-results.xml
retention-days: 14
native-core:
name: Standalone C++ / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# macos-15-intel compiles the AVX2 kernels with AppleClang, the only
# toolchain that rejects '#pragma GCC target' - it guards the exact
# wheel-build configuration used by the macOS Intel release job.
os: [ubuntu-latest, windows-latest, macos-latest, macos-15-intel]
steps:
- uses: actions/checkout@v7
- name: Configure MSVC
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
- name: Build and test with MSVC
if: runner.os == 'Windows'
run: |
cl /nologo /O2 /c /Ithird_party/zstd third_party/zstd/zstd.c /Fo:zstd.obj
cl /nologo /std:c++17 /EHsc /O2 /arch:AVX2 /DWIMF_SIMD_ENABLE_AVX2 /Isrc /c src/v2_simd_avx2.cpp /Fo:v2_simd_avx2.obj
cl /nologo /std:c++17 /EHsc /O2 /DWIMF_SIMD_ENABLE_AVX2 /Isrc /c src/v2_simd.cpp /Fo:v2_simd.obj
cl /nologo /std:c++17 /EHsc /O2 /Isrc /c src/v2_simd.cpp /Fo:v2_simd_scalar.obj
cl /nologo /std:c++17 /EHsc /O2 /Isrc /c src/v2_simd_neon.cpp /Fo:v2_simd_neon.obj
cl /nologo /std:c++17 /EHsc /O2 /Isrc /c src/v2_simd_crc.cpp /Fo:v2_simd_crc.obj
cl /nologo /std:c++17 /EHsc /O2 /Isrc /Ithird_party/zstd /c src/v2_core.cpp /Fo:v2_core.obj
cl /nologo /std:c++17 /EHsc /O2 /Isrc /Ithird_party/zstd /c tests/cpp/test_v2_core.cpp /Fo:test_v2_core.obj
link /nologo test_v2_core.obj v2_core.obj v2_simd.obj v2_simd_avx2.obj v2_simd_neon.obj v2_simd_crc.obj zstd.obj /OUT:v2_core_tests.exe
.\v2_core_tests.exe
cl /nologo /std:c++17 /EHsc /O2 /DWIMF_SIMD_ENABLE_AVX2 /Isrc /c tests/cpp/test_v2_simd.cpp /Fo:test_v2_simd.obj
link /nologo test_v2_simd.obj v2_simd.obj v2_simd_avx2.obj v2_simd_neon.obj v2_simd_crc.obj /OUT:v2_simd_tests.exe
.\v2_simd_tests.exe
cl /nologo /std:c++17 /EHsc /O2 /Isrc /c tests/cpp/test_v2_simd.cpp /Fo:test_v2_simd_scalar.obj
link /nologo test_v2_simd_scalar.obj v2_simd_scalar.obj v2_simd_neon.obj v2_simd_crc.obj /OUT:v2_simd_scalar_tests.exe
.\v2_simd_scalar_tests.exe
cl /nologo /std:c++17 /EHsc /O2 /DWIMF_SIMD_ENABLE_AVX2 /Isrc /c tools/wimf_simd_bench.cpp /Fo:wimf_simd_bench.obj
link /nologo wimf_simd_bench.obj v2_core.obj v2_simd.obj v2_simd_avx2.obj v2_simd_neon.obj v2_simd_crc.obj zstd.obj /OUT:wimf-simd-bench.exe
.\wimf-simd-bench.exe > simd-bench.md
cl /nologo /std:c++17 /EHsc /O2 /Isrc /Ithird_party/zstd /c src/wimf_c.cpp /Fo:wimf_c.obj
cl /nologo /O2 /Isrc /c tests/cpp/test_c_api.c /Fo:test_c_api.obj
link /nologo test_c_api.obj wimf_c.obj v2_core.obj v2_simd.obj v2_simd_avx2.obj v2_simd_neon.obj v2_simd_crc.obj zstd.obj /OUT:c_api_tests.exe
.\c_api_tests.exe
- name: Build and test with the system C++ compiler
if: runner.os != 'Windows'
run: |
cc -O2 -Ithird_party/zstd -c third_party/zstd/zstd.c -o zstd.o
c++ -std=c++17 -O2 -Wall -Wextra -Wno-misleading-indentation -DWIMF_SIMD_ENABLE_AVX2 -Isrc -c src/v2_simd.cpp -o v2_simd.o
c++ -std=c++17 -O2 -Wall -Wextra -Wno-misleading-indentation -Isrc -c src/v2_simd.cpp -o v2_simd_scalar.o
c++ -std=c++17 -O2 -Wall -Wextra -Wno-misleading-indentation -DWIMF_SIMD_ENABLE_AVX2 -Isrc -c src/v2_simd_avx2.cpp -o v2_simd_avx2.o
c++ -std=c++17 -O2 -Wall -Wextra -Wno-misleading-indentation -Isrc -c src/v2_simd_neon.cpp -o v2_simd_neon.o
c++ -std=c++17 -O2 -Wall -Wextra -Wno-misleading-indentation -Isrc -c src/v2_simd_crc.cpp -o v2_simd_crc.o
c++ -std=c++17 -O2 -Wall -Wextra -Wno-misleading-indentation -Isrc -Ithird_party/zstd tests/cpp/test_v2_core.cpp src/v2_core.cpp v2_simd.o v2_simd_avx2.o v2_simd_neon.o v2_simd_crc.o zstd.o -pthread -o v2_core_tests
./v2_core_tests
c++ -std=c++17 -O2 -Wall -Wextra -DWIMF_SIMD_ENABLE_AVX2 -Isrc tests/cpp/test_v2_simd.cpp v2_simd.o v2_simd_avx2.o v2_simd_neon.o v2_simd_crc.o -o v2_simd_tests
./v2_simd_tests
c++ -std=c++17 -O2 -Wall -Wextra -Isrc tests/cpp/test_v2_simd.cpp v2_simd_scalar.o v2_simd_neon.o v2_simd_crc.o -o v2_simd_scalar_tests
./v2_simd_scalar_tests
c++ -std=c++17 -O2 -Wall -Wextra -DWIMF_SIMD_ENABLE_AVX2 -Isrc -Ithird_party/zstd tools/wimf_simd_bench.cpp src/v2_core.cpp v2_simd.o v2_simd_avx2.o v2_simd_neon.o v2_simd_crc.o zstd.o -pthread -o wimf-simd-bench
./wimf-simd-bench > simd-bench.md
cc -std=c11 -O2 -Wall -Wextra -Isrc -c tests/cpp/test_c_api.c -o test_c_api.o
c++ -std=c++17 -O2 -Wall -Wextra -Isrc -Ithird_party/zstd test_c_api.o src/wimf_c.cpp src/v2_core.cpp v2_simd.o v2_simd_avx2.o v2_simd_neon.o v2_simd_crc.o zstd.o -pthread -o c_api_tests
./c_api_tests
- name: Publish SIMD kernel benchmark summary
if: always()
shell: bash
run: |
if [ -f simd-bench.md ]; then
{
echo "## SIMD kernel benchmark (${{ runner.os }})"
echo ""
echo "Rates in MB/s, higher is better. The scalar baseline is included so the"
echo "speedup table is meaningful; compare backends within this table only, since"
echo "each runner is different hardware. Full methodology: docs/simd-benchmarks.md"
echo ""
cat simd-bench.md
echo ""
} >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload SIMD kernel benchmark report
if: always()
uses: actions/upload-artifact@v7
with:
name: simd-bench-${{ matrix.os }}
path: simd-bench.md
retention-days: 30
if-no-files-found: warn
- name: Build, install, and consume the shared C ABI with CMake
shell: bash
run: |
cmake -S . -B cmake-build -DBUILD_SHARED_LIBS=ON -DWIMF_BUILD_TESTS=ON -DWIMF_BUILD_WINDOWS_SHELL=ON -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build --config Release
ctest --test-dir cmake-build --build-config Release --output-on-failure
cmake --install cmake-build --config Release --prefix "$PWD/cmake-install"
cmake -S tests/cmake-consumer -B consumer-build -DCMAKE_PREFIX_PATH="$PWD/cmake-install" -DCMAKE_BUILD_TYPE=Release
cmake --build consumer-build --config Release
cmake --build cmake-build --config Release --target package
- name: Upload native failure diagnostics
if: ${{ failure() && runner.os == 'Windows' }}
uses: actions/upload-artifact@v7
with:
name: native-failure-windows
path: cmake-build/native-tool-test/*
if-no-files-found: warn
retention-days: 7
- name: Upload native SDK test package
uses: actions/upload-artifact@v7
with:
name: native-sdk-${{ matrix.os }}
path: cmake-build/WIMF-SDK-*
if-no-files-found: error
retention-days: 14
wasm-core:
name: WebAssembly core conformance
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Install Emscripten
run: |
sudo apt-get update
sudo apt-get install --yes emscripten
- name: Build and run the synchronous codec as WebAssembly
run: |
emcc -O2 -Ithird_party/zstd -c third_party/zstd/zstd.c -o zstd-wasm.o
em++ -std=c++17 -O2 -fexceptions -Isrc -c src/v2_simd.cpp -o v2_simd-wasm.o
em++ -std=c++17 -O2 -fexceptions -Isrc -c src/v2_simd_avx2.cpp -o v2_simd_avx2-wasm.o
em++ -std=c++17 -O2 -fexceptions -Isrc -c src/v2_simd_neon.cpp -o v2_simd_neon-wasm.o
em++ -std=c++17 -O2 -fexceptions -Isrc -c src/v2_simd_crc.cpp -o v2_simd_crc-wasm.o
em++ -std=c++17 -O2 -fexceptions -Isrc -Ithird_party/zstd tests/cpp/test_v2_core.cpp src/v2_core.cpp v2_simd-wasm.o v2_simd_avx2-wasm.o v2_simd_neon-wasm.o v2_simd_crc-wasm.o zstd-wasm.o -sDISABLE_EXCEPTION_CATCHING=0 -sEXIT_RUNTIME=1 -sENVIRONMENT=node -sWASM_ASYNC_COMPILATION=0 -sALLOW_MEMORY_GROWTH=1 -o wimf-wasm-tests.js
node wimf-wasm-tests.js
visual-report:
name: Visual codec report
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- run: python -m pip install pytest pybind11 numpy pillow zstandard setuptools wheel
- run: python setup.py build_ext --inplace
- run: python tests/generate_ci_report.py --input .github/assets/dark.png --output codec-report
- name: Render WIMF Studio states
run: |
if ! command -v xvfb-run >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y xvfb
fi
xvfb-run -a python tests/generate_studio_screenshots.py codec-report/studio
- name: Upload visual evidence
id: visual-artifact
uses: actions/upload-artifact@v7
with:
name: codec-visual-report
path: codec-report/
retention-days: 30
- name: Publish job summary
run: |
cat codec-report/summary.md >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "[Download decoded images, difference heatmap, metrics, and WIMF files](${{ steps.visual-artifact.outputs.artifact-url }})" >> "$GITHUB_STEP_SUMMARY"
package:
name: Package metadata and source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- run: python -m pip install build twine
- run: python -m build --sdist
- run: python -m twine check dist/*
native-sanitizers:
name: Native parser sanitizers
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Build parser mutation test with ASan and UBSan
run: |
cc -O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined -Ithird_party/zstd -c third_party/zstd/zstd.c -o zstd.o
c++ -std=c++17 -O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined \
-Wall -Wextra -Wno-misleading-indentation -Isrc -c src/v2_simd.cpp -o v2_simd.o
c++ -std=c++17 -O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined \
-Wall -Wextra -DWIMF_SIMD_ENABLE_AVX2 -Isrc -c src/v2_simd_avx2.cpp -o v2_simd_avx2.o
c++ -std=c++17 -O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined \
-Wall -Wextra -Wno-misleading-indentation -Isrc -c src/v2_simd_neon.cpp -o v2_simd_neon.o
c++ -std=c++17 -O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined \
-Wall -Wextra -Wno-misleading-indentation -Isrc -c src/v2_simd_crc.cpp -o v2_simd_crc.o
c++ -std=c++17 -O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined \
-Wall -Wextra -Wno-misleading-indentation -Isrc -Ithird_party/zstd \
tests/cpp/fuzz_v2_parser.cpp src/v2_core.cpp v2_simd.o v2_simd_avx2.o v2_simd_neon.o v2_simd_crc.o zstd.o -pthread -o fuzz_v2_parser
- run: ./fuzz_v2_parser
codec-benchmark:
name: Python vs C++ WIM2 / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
continue-on-error: true
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip
- run: python -m pip install pybind11 numpy pillow zstandard setuptools wheel
- run: python setup.py build_ext --inplace
- name: Benchmark WIM2 still images
shell: bash
run: |
python benchmarks/bench_codecs.py --still-size 512 > codec-benchmark.json
python benchmarks/codec_summary.py codec-benchmark.json >> "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@v7
with:
name: codec-benchmark-${{ matrix.os }}
path: codec-benchmark.json
retention-days: 30