name: Regression testing on: - push - pull_request env: # Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/) TERM: xterm-256color CLICOLOR: 1 CLICOLOR_FORCE: 1 CMAKE_COLOR_DIAGNOSTICS: ON # Tells CMake-generated build systems to have colored output. CMAKE_CONFIG_TYPE: Debug # `cmake --build` now implies `--config Debug`. # Approximate number of CPU cores in GitHub's runners as of 2026-03-18: # https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories CMAKE_BUILD_PARALLEL_LEVEL: 4 # `cmake --build` now implies `--parallel 4`. CMAKE_INSTALL_PARALLEL_LEVEL: 4 # `cmake --install` now implies `--parallel 4`. CTEST_PARALLEL_LEVEL: 0 # `ctest` now implies `--parallel 0` (number of logical CPUs). CTEST_NO_TESTS_ACTION: error # Make CTest fail if it cannot find any tests. (That should never happen.) CTEST_OUTPUT_ON_FAILURE: ON # CTest reports test program output on failure. GIT_CONFIG_COUNT: 1 GIT_CONFIG_KEY_0: color.ui GIT_CONFIG_VALUE_0: always # Colorful output is helpful even though CI is not considered to be a terminal. # We instruct CMake to download and build third-party projects outside of our source tree, # otherwise they can trigger `-Werror=dev` (from the `develop` preset). DEPS_ROOT_DIR: ~/_deps # Note that this needs to be used in a position where Bash will trigger tilde expansion! # We use bash syntax across OSes for consistency unless otherwise specified defaults: run: shell: bash jobs: unix: strategy: matrix: os: [ubuntu-22.04, macos-15-intel, macos-26] cxx: [g++, clang++] buildsys: [make, cmake] exclude: # Don't use `g++` on macOS; it's just an alias to `clang++`. - { os: macos-15-intel, cxx: g++ } - { os: macos-26, cxx: g++ } fail-fast: false runs-on: ${{ matrix.os }} steps: - name: Checkout repo uses: actions/checkout@v6 - name: Install deps run: | .github/scripts/install_deps.sh ${{ matrix.os }} - name: Build & install using Make if: matrix.buildsys == 'make' run: | make develop -kj Q= CXX=${{ matrix.cxx }} sudo make install -j Q= - name: Build & install using CMake if: matrix.buildsys == 'cmake' # Since GitHub's runners are basically kitchen sinks, # the Mono framework exposes a libpng 1.4.x header, breaking everything. # Searching frameworks last makes Homebrew's libpng be discovered first, which works. # Note that since this is specific to our CI environment, the workaround is # better applied here than in our CMakeLists, where it could affect and break someone else. run: | cmake -B build -G Ninja --preset develop -DCMAKE_FIND_FRAMEWORK=LAST -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DTESTS_OS_NAME=${{ matrix.os }} cmake --build build -- -k 0 sudo cmake --install build --verbose - name: Package binaries run: | mkdir bins cp rgb{asm,link,fix,gfx} bins - name: Upload binaries uses: actions/upload-artifact@v7 with: name: rgbds-canary-${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.buildsys }} path: bins if-no-files-found: error - name: Compute test dependency cache params id: test-deps-cache-params run: | paths=$(test/fetch-test-deps.sh --get-paths) hash=$(test/fetch-test-deps.sh --get-hash) tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT - name: Check test dependency repositories cache id: test-deps-cache uses: actions/cache@v5 with: path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }} key: ${{ matrix.os }}-${{ steps.test-deps-cache-params.outputs.hash }} - name: Fetch test dependency repositories if: steps.test-deps-cache.outputs.cache-hit != 'true' continue-on-error: true run: | test/fetch-test-deps.sh - name: Install test dependency dependencies run: | test/fetch-test-deps.sh --get-deps ${{ matrix.os }} - name: Run tests using our script if: matrix.buildsys == 'make' run: | CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }} - name: Run tests using CTest if: matrix.buildsys == 'cmake' run: | ctest --test-dir build --schedule-random macos-static: runs-on: macos-26 steps: - name: Checkout repo uses: actions/checkout@v6 - name: Install deps run: | .github/scripts/install_deps.sh macos lld - name: Cache library deps uses: actions/cache@v5 with: path: ${{ env.DEPS_ROOT_DIR }}/*-tmp/ key: dep-srcs-${{ hashFiles('cmake/deps.cmake') }} enableCrossOsArchive: true - name: Build & install run: | cmake -B build -G Ninja --preset macos-static -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}" -DTESTS_OS_NAME=macos cmake --build build -- -k 0 env: LDFLAGS: -fuse-ld=lld # cmake/macos-static.cmake comments explain why we use lld. - name: Package binaries run: | mkdir bins cp rgb{asm,link,fix,gfx} bins - name: Upload binaries uses: actions/upload-artifact@v7 with: name: rgbds-canary-macos-static path: bins if-no-files-found: error - name: Compute test dependency cache params id: test-deps-cache-params run: | paths=$(test/fetch-test-deps.sh --get-paths) hash=$(test/fetch-test-deps.sh --get-hash) tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT - name: Check test dependency repositories cache id: test-deps-cache uses: actions/cache@v5 with: path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }} key: macos-26-${{ steps.test-deps-cache-params.outputs.hash }} - name: Fetch test dependency repositories if: steps.test-deps-cache.outputs.cache-hit != 'true' continue-on-error: true run: | test/fetch-test-deps.sh - name: Install test dependency dependencies run: | test/fetch-test-deps.sh --get-deps macos - name: Run tests run: | ctest --test-dir build --schedule-random windows: strategy: matrix: bits: [32, 64] os: [windows-2022, windows-2025] fail-fast: false runs-on: ${{ matrix.os }} steps: - name: Checkout repo uses: actions/checkout@v6 - name: Install deps run: | bash .github/scripts/install_deps.sh ${{ matrix.os }} - name: Cache library deps uses: actions/cache@v5 with: path: ${{ env.DEPS_ROOT_DIR }}/*-tmp/ key: dep-srcs-${{ hashFiles('cmake/deps.cmake') }} enableCrossOsArchive: true - name: Build Windows binaries shell: cmd run: | # ASan seems to be broken on Windows, so we disable it. call .github\scripts\msvc-env.bat ${{ matrix.bits }} cmake -B build -G Ninja --preset develop -DSANITIZERS=OFF -DTESTS_OS_NAME=${{ matrix.os }} ^ -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}" -DCMAKE_C_FLAGS="/nologo" cmake --build build -- -k 0 - name: Package binaries working-directory: build run: | cpack -DCPACK_PACKAGE_FILE_NAME=rgbds-win${{ matrix.bits }} -G ZIP --verbose - name: Upload Windows binaries uses: actions/upload-artifact@v7 with: name: rgbds-canary-w${{ matrix.bits }}-${{ matrix.os }} path: build/rgbds-win${{ matrix.bits }}.zip if-no-files-found: error - name: Compute test dependency cache params id: test-deps-cache-params run: | paths=$(test/fetch-test-deps.sh --get-paths) hash=$(test/fetch-test-deps.sh --get-hash) tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT - name: Check test dependency repositories cache id: test-deps-cache uses: actions/cache@v5 with: path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }} key: ${{ matrix.os }}-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }} - name: Fetch test dependency repositories if: steps.test-deps-cache.outputs.cache-hit != 'true' continue-on-error: true run: | test/fetch-test-deps.sh - name: Install test dependency dependencies run: | test/fetch-test-deps.sh --get-deps ${{ matrix.os }} - name: Run tests using CTest run: | ctest --test-dir build --schedule-random windows-mingw-build: strategy: matrix: bits: [32, 64] fail-fast: false runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v6 - name: Install deps run: | .github/scripts/install_deps.sh ubuntu mingw${{ matrix.bits }} - name: Cache library deps uses: actions/cache@v5 with: path: ${{ env.DEPS_ROOT_DIR }}/*-tmp/ key: dep-srcs-${{ hashFiles('cmake/deps.cmake') }} enableCrossOsArchive: true - name: Cross-build Windows binaries run: | # MinGW does not support `--preset develop` sanitizers ASan or UBSan. dll_search_dir=$(printf '%s\n' /usr/lib/gcc/*-w64-mingw32/*-win32 | tee -a /dev/stderr) cmake -B build -G Ninja --preset develop -DSANITIZERS=OFF --toolchain cmake/toolchain-mingw${{ matrix.bits }}.cmake \ -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}" -DDLL_SEARCH_DIRS="$dll_search_dir" cmake --build build -- -k 0 - name: Package binaries run: | cmake --install build --prefix . --verbose --component binaries cmake --install build --prefix . --verbose --component shared-libs - name: Upload Windows binaries uses: actions/upload-artifact@v7 with: name: rgbds-canary-mingw-win${{ matrix.bits }} path: bin if-no-files-found: error - name: Upload Windows test binaries uses: actions/upload-artifact@v7 with: name: testing-programs-mingw-win${{ matrix.bits }} path: | test/gfx/randtilegen.exe test/gfx/rgbgfx_test.exe if-no-files-found: error windows-mingw-testing: needs: windows-mingw-build strategy: matrix: os: [windows-2022, windows-2025] bits: [32, 64] fail-fast: false runs-on: ${{ matrix.os }} steps: - name: Checkout repo uses: actions/checkout@v6 - name: Retrieve binaries uses: actions/download-artifact@v8 with: name: rgbds-canary-mingw-win${{ matrix.bits }} path: bins - name: Retrieve test binaries uses: actions/download-artifact@v8 with: name: testing-programs-mingw-win${{ matrix.bits }} path: test/gfx - name: Extract binaries run: | cp bins/* . cp bins/*.dll test/gfx - name: Compute test dependency cache params id: test-deps-cache-params run: | paths=$(test/fetch-test-deps.sh --get-paths) hash=$(test/fetch-test-deps.sh --get-hash) tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT - name: Check test dependency repositories cache id: test-deps-cache uses: actions/cache@v5 with: path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }} key: mingw-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }} - name: Fetch test dependency repositories if: steps.test-deps-cache.outputs.cache-hit != 'true' continue-on-error: true run: | test/fetch-test-deps.sh - name: Install test dependency dependencies run: | test/fetch-test-deps.sh --get-deps ${{ matrix.os }} - name: Run tests run: | test/run-tests.sh --os ${{ matrix.os }} cygwin: strategy: matrix: bits: [32, 64] include: - bits: 32 arch: x86 - bits: 64 arch: x86_64 fail-fast: false runs-on: windows-2022 timeout-minutes: 30 defaults: run: shell: C:\cygwin\bin\env.exe CYGWIN_NOWINPATH=1 CHERE_INVOKING=1 C:\cygwin\bin\bash.exe -o igncr '{0}' steps: - name: Checkout repo uses: actions/checkout@v6 - name: Setup Cygwin uses: cygwin/cygwin-install-action@v6 with: platform: ${{ matrix.arch }} packages: >- bison gcc-g++ git libpng-devel make pkg-config - name: Build & install using Make run: | # Cygwin does not support `make develop` sanitizers ASan or UBSan make -kj Q= make install -j Q= - name: Run tests run: | test/run-tests.sh --only-internal freebsd: runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo uses: actions/checkout@v6 - name: Build & test using CMake on FreeBSD uses: vmactions/freebsd-vm@v1 with: envs: >- TERM CLICOLOR CLICOLOR_FORCE CMAKE_COLOR_DIAGNOSTICS CMAKE_CONFIG_TYPE CMAKE_BUILD_PARALLEL_LEVEL CTEST_PARALLEL_LEVEL CTEST_NO_TESTS_ACTION CTEST_OUTPUT_ON_FAILURE GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0 release: "14.3" usesh: true prepare: | .github/scripts/install_deps.sh freebsd run: | # Leak detection is not supported on FreeBSD, so disable it. cmake -B build --preset develop -DTESTS_OS_NAME=freebsd cmake --build build --verbose -- -k ASAN_OPTIONS=detect_leaks=0 ctest --test-dir build --schedule-random --label-exclude external cmake --install build --verbose