Speed workflows up (#3418)

Split Linux and macOS workflows into separate files.
Run macOS workflows only on main branch.
Rename workflows and jobs consistently.
Remove single-value matrix dimensions.
Remove ci-macos-static-sanitized.
diff --git a/.github/workflows/ci-android-emulator-tests.yml b/.github/workflows/ci-android-emulator-tests.yml
index 450bae6..4bd2f6f 100644
--- a/.github/workflows/ci-android-emulator-tests.yml
+++ b/.github/workflows/ci-android-emulator-tests.yml
@@ -22,11 +22,13 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-and-run-android-jni-tests:
+  build-android-jni-and-run-tests:
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
 
+    name: build-android-jni-and-run-tests
+
     steps:
       - name: Checkout the repository
         uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff --git a/.github/workflows/ci-android-jni.yml b/.github/workflows/ci-android-jni.yml
index dc66565..6a2649e 100644
--- a/.github/workflows/ci-android-jni.yml
+++ b/.github/workflows/ci-android-jni.yml
@@ -15,6 +15,8 @@
     strategy:
       fail-fast: false
 
+    name: build-android-jni
+
     steps:
       - name: Checkout the repository
         uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff --git a/.github/workflows/ci-c-warnings.yml b/.github/workflows/ci-c-warnings.yml
index bf9c7f3..5004ee2 100644
--- a/.github/workflows/ci-c-warnings.yml
+++ b/.github/workflows/ci-c-warnings.yml
@@ -1,5 +1,3 @@
-# This is a copy of ci-unix-shared-installed.yml for finding bugs when adding warnings.
-
 name: CI C conformance
 on: [push, pull_request]
 
@@ -12,7 +10,7 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-shared-installed:
+  build-c-warnings:
     strategy:
       fail-fast: false
       # Generate the configurations:
@@ -23,6 +21,8 @@
 
     runs-on: ${{ matrix.os }}
 
+    name: build-c-warnings (${{ matrix.os }}, case ${{ matrix.case }})
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-disable-gtest.yml b/.github/workflows/ci-disable-gtest.yml
index 943d107..000449a 100644
--- a/.github/workflows/ci-disable-gtest.yml
+++ b/.github/workflows/ci-disable-gtest.yml
@@ -1,9 +1,3 @@
-# This is a copy of ci-unix-static.yml with gtest disabled. It differs from ci-unix-static.yml as follows:
-#
-#   * The os matrix consists of ubuntu-latest only.
-#   * Does not build libgav1. (Building libgav1 would enable CXX in CMakeLists.txt.)
-#   * Disables gtest.
-
 name: CI Disable GTest
 on:
   push:
@@ -25,16 +19,17 @@
 
 jobs:
   build-disable-gtest:
-    runs-on: ${{ matrix.os }}
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest]
         include:
           - runs-on: ubuntu-latest
             compiler: gcc
             gcc: 14
 
+    name: build-disable-gtest (ubuntu)
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-format-check.yml b/.github/workflows/ci-format-check.yml
index 598fa58..498f9c1 100644
--- a/.github/workflows/ci-format-check.yml
+++ b/.github/workflows/ci-format-check.yml
@@ -12,6 +12,9 @@
 jobs:
   clang-format-check:
     runs-on: ubuntu-latest
+
+    name: clang-format-check
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
@@ -24,6 +27,9 @@
 
   cmake-format-check:
     runs-on: ubuntu-latest
+
+    name: cmake-format-check
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-fuzztest.yml b/.github/workflows/ci-fuzztest.yml
index b2e4df0..c011ce3 100644
--- a/.github/workflows/ci-fuzztest.yml
+++ b/.github/workflows/ci-fuzztest.yml
@@ -16,15 +16,14 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-shared-local:
-    runs-on: ${{ matrix.os }}
+  build-fuzztest:
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest]
         libyuv: [OFF, LOCAL]
 
-    name: build-shared-local-fuzztest
+    name: build-fuzztest (ubuntu, libyuv ${{ matrix.libyuv }})
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff --git a/.github/workflows/ci-linux-artifacts.yml b/.github/workflows/ci-linux-artifacts.yml
index c0b567d..1bde3f5 100644
--- a/.github/workflows/ci-linux-artifacts.yml
+++ b/.github/workflows/ci-linux-artifacts.yml
@@ -13,11 +13,11 @@
 
 jobs:
   build-linux-artifacts:
-    runs-on: ${{ matrix.os }}
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
-      matrix:
-        os: [ubuntu-latest]
+
+    name: build-linux-artifacts
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff --git a/.github/workflows/ci-linux-coverage.yml b/.github/workflows/ci-linux-coverage.yml
index 9be72e9..28d8755 100644
--- a/.github/workflows/ci-linux-coverage.yml
+++ b/.github/workflows/ci-linux-coverage.yml
@@ -12,12 +12,12 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-shared-run-golden-tests:
-    runs-on: ${{ matrix.os }}
+  build-shared-local-run-code-coverage:
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
-      matrix:
-        os: [ubuntu-latest]
+
+    name: build-shared-local-run-code-coverage (ubuntu)
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff --git a/.github/workflows/ci-linux-golden-tests.yml b/.github/workflows/ci-linux-golden-tests.yml
index 835cac2..10cc084 100644
--- a/.github/workflows/ci-linux-golden-tests.yml
+++ b/.github/workflows/ci-linux-golden-tests.yml
@@ -14,17 +14,18 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-shared-run-golden-tests:
-    runs-on: ${{ matrix.os }}
+  build-static-local-run-golden-tests:
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest]
         include:
           - runs-on: ubuntu-latest
             compiler: gcc
             gcc: 14
 
+    name: build-static-local-run-golden-tests (ubuntu)
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-linux-oldest-cmake.yml b/.github/workflows/ci-linux-oldest-cmake.yml
index 37c4a42..5ce19c8 100644
--- a/.github/workflows/ci-linux-oldest-cmake.yml
+++ b/.github/workflows/ci-linux-oldest-cmake.yml
@@ -12,12 +12,12 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-shared-local:
+  build-shared-local-oldest-cmake:
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
 
-    name: build-linux-oldest-cmake
+    name: build-shared-local-oldest-cmake (ubuntu)
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff --git a/.github/workflows/ci-unix-shared-installed.yml b/.github/workflows/ci-linux-shared-installed.yml
similarity index 69%
rename from .github/workflows/ci-unix-shared-installed.yml
rename to .github/workflows/ci-linux-shared-installed.yml
index f426ca8..0bc38e1 100644
--- a/.github/workflows/ci-unix-shared-installed.yml
+++ b/.github/workflows/ci-linux-shared-installed.yml
@@ -1,7 +1,4 @@
-# This is a copy of ci-unix-shared-local.yml for building shared libraries
-# with an additional build configuration (using installed deps and dav1d).
-
-name: CI Unix Shared Installed
+name: CI Linux Shared Installed
 on: [push, pull_request]
 
 permissions:
@@ -14,31 +11,23 @@
 
 jobs:
   build-shared-installed:
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
-      # Generate the configurations:
-      # Ubuntu with gcc 14 with oldest-cmake set to true or false
-      # OSX with default gcc and CMake (oldest-cmake is unused on OSX)
       matrix:
-        os: [ubuntu-latest, macos-latest]
         oldest-cmake: [false, true]
         include:
-          # Add a gcc version on Ubuntu only
           - os: ubuntu-latest
             compiler: gcc
             gcc: 14
-        exclude:
-          # Do not use the oldest CMake on OSX
-          - os: macos-latest
-            oldest-cmake: true
-    runs-on: ${{ matrix.os }}
+
+    name: build-shared-installed (ubuntu, oldest-cmake ${{ matrix.oldest-cmake }})
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           persist-credentials: false
       - uses: ./.github/actions/setup-linux
-        if: runner.os == 'Linux'
         with:
           codec-aom: "SYSTEM"
           codec-dav1d: "SYSTEM"
@@ -50,20 +39,6 @@
           libyuv: "SYSTEM"
           oldest-cmake: ${{ matrix.oldest-cmake }}
           zlibpng: "SYSTEM"
-      - uses: ./.github/actions/setup-macos
-        if: runner.os == 'macOS'
-        with:
-          codec-aom: "SYSTEM"
-          codec-dav1d: "SYSTEM"
-          codec-rav1e: "SYSTEM"
-          codec-svt: "SYSTEM"
-          gtest: "SYSTEM"
-          libjpeg-turbo: "SYSTEM"
-          zlibpng: "SYSTEM"
-      - name: Disable libyuv on macOS
-        # libyuv is not available with brew.
-        if: runner.os == 'macOS'
-        run: echo "CMAKE_AVIF_FLAGS=\"-DAVIF_LIBYUV=OFF\""  >> $GITHUB_ENV
 
       - name: Prepare libavif (cmake)
         run: >
diff --git a/.github/workflows/ci-unix-shared-local.yml b/.github/workflows/ci-linux-shared-local.yml
similarity index 74%
rename from .github/workflows/ci-unix-shared-local.yml
rename to .github/workflows/ci-linux-shared-local.yml
index 84f517b..6c34573 100644
--- a/.github/workflows/ci-unix-shared-local.yml
+++ b/.github/workflows/ci-linux-shared-local.yml
@@ -1,8 +1,4 @@
-# This is a copy of ci-unix-static.yml for building shared libraries. It differs from ci-unix-static.yml as follows:
-#
-#   * Does not build rav1e, SVT-AV1 nor libgav1.
-
-name: CI Unix Shared Local
+name: CI Linux Shared Local
 on: [push, pull_request]
 
 permissions:
@@ -15,25 +11,23 @@
 
 jobs:
   build-shared-local:
-    runs-on: ${{ matrix.os }}
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest, macos-latest]
         libyuv: [OFF, LOCAL]
         include:
           - runs-on: ubuntu-latest
             compiler: gcc
             gcc: 14
 
-    name: build-shared-local (${{ matrix.os }}, libyuv ${{ matrix.libyuv }})
+    name: build-shared-local (ubuntu, libyuv ${{ matrix.libyuv }})
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           persist-credentials: false
       - uses: ./.github/actions/setup-linux
-        if: runner.os == 'Linux'
         with:
           codec-aom: "LOCAL"
           codec-dav1d: "LOCAL"
@@ -42,13 +36,6 @@
           libxml2: "LOCAL"
           libyuv: ${{ matrix.libyuv }}
           zlibpng: "SYSTEM"
-      - uses: ./.github/actions/setup-macos
-        if: runner.os == 'macOS'
-        with:
-          codec-aom: "LOCAL"
-          codec-dav1d: "LOCAL"
-          libjpeg-turbo: "SYSTEM"
-          zlibpng: "SYSTEM"
 
       - name: Prepare libavif (cmake)
         run: >
diff --git a/.github/workflows/ci-unix-static-av2.yml b/.github/workflows/ci-linux-static-av2.yml
similarity index 96%
rename from .github/workflows/ci-unix-static-av2.yml
rename to .github/workflows/ci-linux-static-av2.yml
index 9a20bad..025ec63 100644
--- a/.github/workflows/ci-unix-static-av2.yml
+++ b/.github/workflows/ci-linux-static-av2.yml
@@ -1,4 +1,4 @@
-name: CI Unix Static AV2
+name: CI Linux Static AV2
 on:
   push:
   pull_request:
@@ -18,7 +18,7 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-static-av2:
+  build-static-local-av2:
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
@@ -29,6 +29,8 @@
             compiler: gcc
             gcc: 14
 
+    name: build-static-local-av2 (ubuntu)
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-unix-static-sanitized-memory.yml b/.github/workflows/ci-linux-static-sanitized-memory.yml
similarity index 93%
rename from .github/workflows/ci-unix-static-sanitized-memory.yml
rename to .github/workflows/ci-linux-static-sanitized-memory.yml
index e777a68..5a4ca15 100644
--- a/.github/workflows/ci-unix-static-sanitized-memory.yml
+++ b/.github/workflows/ci-linux-static-sanitized-memory.yml
@@ -1,5 +1,5 @@
 # Memory sanitizer needs to be in its own file because it is slower than other sanitizers.
-name: CI Unix Static Sanitized Memory
+name: CI Linux Static Sanitized Memory
 on:
   push:
   pull_request:
@@ -11,19 +11,20 @@
   contents: read
 
 jobs:
-  build-static-sanitized-memory:
+  build-static-local-sanitized-memory:
     runs-on: ubuntu-latest
 
     env:
       CC: clang
       CXX: clang++
 
+    name: build-static-local-sanitized-memory (ubuntu)
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           persist-credentials: false
       - uses: ./.github/actions/setup-linux
-        if: runner.os == 'Linux'
         id: setup_linux
         with:
           codec-aom: "LOCAL"
@@ -31,7 +32,7 @@
           libyuv: "LOCAL"
           extra-cache-key: memory
       - id: cache-hit
-        run: echo "hit=${{ (runner.os == 'Linux' && steps.setup_linux.outputs.ext-cache-hit == 'true') || (runner.os == 'macOS' && steps.setup_macos.outputs.ext-cache-hit == 'true') }}" >> "$GITHUB_OUTPUT"
+        run: echo "hit=${{ steps.setup_linux.outputs.ext-cache-hit == 'true' }}" >> "$GITHUB_OUTPUT"
 
       - name: Build cxx and cxxabi
         run: |
diff --git a/.github/workflows/ci-unix-static-sanitized.yml b/.github/workflows/ci-linux-static-sanitized.yml
similarity index 82%
rename from .github/workflows/ci-unix-static-sanitized.yml
rename to .github/workflows/ci-linux-static-sanitized.yml
index da3a7ab..2a51fcd 100644
--- a/.github/workflows/ci-unix-static-sanitized.yml
+++ b/.github/workflows/ci-linux-static-sanitized.yml
@@ -1,4 +1,4 @@
-name: CI Unix Static Sanitized
+name: CI Linux Static Sanitized
 on:
   push:
   pull_request:
@@ -13,12 +13,11 @@
   contents: read
 
 jobs:
-  build-static-sanitized:
-    runs-on: ${{ matrix.os }}
+  build-static-local-sanitized:
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest, macos-latest]
         # Memory sanitizer needs to be in its own file because it is slower than other sanitizers.
         sanitizer: [address, thread, undefined]
 
@@ -26,12 +25,13 @@
       CC: clang
       CXX: clang++
 
+    name: build-static-local-sanitized-${{ matrix.sanitizer }} (ubuntu)
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           persist-credentials: false
       - uses: ./.github/actions/setup-linux
-        if: runner.os == 'Linux'
         id: setup_linux
         with:
           codec-aom: "LOCAL"
@@ -40,18 +40,8 @@
           libjpeg-turbo: "SYSTEM"
           libyuv: "LOCAL"
           zlibpng: "SYSTEM"
-      - uses: ./.github/actions/setup-macos
-        if: runner.os == 'macOS'
-        id: setup_macos
-        with:
-          codec-aom: "LOCAL"
-          codec-dav1d: "LOCAL"
-          extra-cache-key: ${{ matrix.sanitizer }}
-          libjpeg-turbo: "SYSTEM"
-          libyuv: "LOCAL"
-          zlibpng: "SYSTEM"
       - id: cache-hit
-        run: echo "hit=${{ (runner.os == 'Linux' && steps.setup_linux.outputs.ext-cache-hit == 'true') || (runner.os == 'macOS' && steps.setup_macos.outputs.ext-cache-hit == 'true') }}" >> "$GITHUB_OUTPUT"
+        run: echo "hit=${{ steps.setup_linux.outputs.ext-cache-hit == 'true' }}" >> "$GITHUB_OUTPUT"
 
       - name: Set FLAGS for sanitizers
         run: |
diff --git a/.github/workflows/ci-unix-static.yml b/.github/workflows/ci-linux-static.yml
similarity index 80%
rename from .github/workflows/ci-unix-static.yml
rename to .github/workflows/ci-linux-static.yml
index 10d3182..ad76d2d 100644
--- a/.github/workflows/ci-unix-static.yml
+++ b/.github/workflows/ci-linux-static.yml
@@ -1,4 +1,4 @@
-name: CI Unix Static
+name: CI Linux Static
 on:
   push:
   pull_request:
@@ -18,24 +18,24 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-static:
-    runs-on: ${{ matrix.os }}
+  build-static-local:
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest, macos-latest]
         build-type: [Release, Debug]
         include:
           - runs-on: ubuntu-latest
             compiler: gcc
             gcc: 14
 
+    name: build-static-local (ubuntu, ${{ matrix.build-type }})
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           persist-credentials: false
       - uses: ./.github/actions/setup-linux
-        if: runner.os == 'Linux'
         with:
           codec-aom: "LOCAL"
           codec-dav1d: "LOCAL"
@@ -46,15 +46,6 @@
           libxml2: "LOCAL"
           libyuv: "LOCAL"
           zlibpng: "SYSTEM"
-      - uses: ./.github/actions/setup-macos
-        if: runner.os == 'macOS'
-        with:
-          codec-aom: "LOCAL"
-          codec-dav1d: "LOCAL"
-          codec-rav1e: "LOCAL"
-          extra-cache-key: ${{ matrix.build-type }}
-          libjpeg-turbo: "SYSTEM"
-          zlibpng: "SYSTEM"
 
       - name: Prepare libavif (cmake)
         run: >
@@ -76,11 +67,6 @@
         working-directory: ./build
         run: ctest -j $(getconf _NPROCESSORS_ONLN) --output-on-failure
 
-      - name: Set CC on macOS
-        if: ${{ runner.os == 'macOS' }}
-        run:
-          echo "CC=cc" >> $GITHUB_ENV
-        shell: bash
       - name: Check static link bundling
         run: |
           ${{ env.CC }} -o avifenc  -I./apps/shared -I./third_party/iccjpeg -I./include apps/avifenc.c \
diff --git a/.github/workflows/ci-macos-artifacts.yml b/.github/workflows/ci-macos-artifacts.yml
index 33bb607..52b5c85 100644
--- a/.github/workflows/ci-macos-artifacts.yml
+++ b/.github/workflows/ci-macos-artifacts.yml
@@ -19,6 +19,8 @@
       matrix:
         os: [macos-latest]
 
+    name: build-macos-artifacts
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-macos-shared-installed.yml b/.github/workflows/ci-macos-shared-installed.yml
new file mode 100644
index 0000000..16bf9af
--- /dev/null
+++ b/.github/workflows/ci-macos-shared-installed.yml
@@ -0,0 +1,69 @@
+name: CI macOS Shared Installed
+on:
+  push:
+    branches:
+      - main
+
+permissions:
+  contents: read
+
+jobs:
+  build-shared-installed:
+    runs-on: macos-latest
+    strategy:
+      fail-fast: false
+
+    name: build-shared-installed (macos)
+
+    steps:
+      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+        with:
+          persist-credentials: false
+      - uses: ./.github/actions/setup-macos
+        with:
+          codec-aom: "SYSTEM"
+          codec-dav1d: "SYSTEM"
+          codec-rav1e: "SYSTEM"
+          codec-svt: "SYSTEM"
+          gtest: "SYSTEM"
+          libjpeg-turbo: "SYSTEM"
+          zlibpng: "SYSTEM"
+      - name: Disable libyuv
+        # libyuv is not available with brew.
+        run: echo "CMAKE_AVIF_FLAGS=\"-DAVIF_LIBYUV=OFF\""  >> $GITHUB_ENV
+
+      - name: Prepare libavif (cmake)
+        run: >
+          cmake -G Ninja -S . -B build
+          -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON
+          -DAVIF_CODEC_AOM=SYSTEM
+          -DAVIF_CODEC_AOM_DECODE=OFF -DAVIF_CODEC_AOM_ENCODE=ON
+          -DAVIF_CODEC_DAV1D=SYSTEM -DAVIF_CODEC_RAV1E=SYSTEM
+          -DAVIF_CODEC_SVT=SYSTEM
+          -DAVIF_BUILD_EXAMPLES=ON -DAVIF_BUILD_APPS=ON
+          -DAVIF_BUILD_TESTS=ON -DAVIF_GTEST=SYSTEM
+          -DAVIF_BUILD_GDK_PIXBUF=ON -DCMAKE_INSTALL_PREFIX=./build/install
+          -DAVIF_ENABLE_WERROR=ON ${{ env.CMAKE_AVIF_FLAGS }}
+      - name: Build libavif
+        run: cmake --build build --config Release --parallel 4
+      - name: Run AVIF Tests
+        working-directory: ./build
+        run: ctest -j $(getconf _NPROCESSORS_ONLN) --output-on-failure
+      - name: Install AVIF
+        run: cmake --install build
+      - name: Test installed cmake
+        working-directory: ./build
+        run: >
+          mkdir test && cd test
+
+          echo "cmake_minimum_required(VERSION 3.22)
+                project(FindPackageTest)
+                message(STATUS ${CMAKE_PREFIX_PATH})
+                find_package(libavif REQUIRED)
+                if(TARGET avif)
+                  message(STATUS "\""avif found"\"")
+                else()
+                  message(FATAL_ERROR "\""avif not found"\"")
+                endif()" >> CMakeLists.txt
+
+          cmake . -DCMAKE_PREFIX_PATH=../install
diff --git a/.github/workflows/ci-unix-shared-local.yml b/.github/workflows/ci-macos-shared-local.yml
similarity index 69%
copy from .github/workflows/ci-unix-shared-local.yml
copy to .github/workflows/ci-macos-shared-local.yml
index 84f517b..16e2f1b 100644
--- a/.github/workflows/ci-unix-shared-local.yml
+++ b/.github/workflows/ci-macos-shared-local.yml
@@ -1,9 +1,8 @@
-# This is a copy of ci-unix-static.yml for building shared libraries. It differs from ci-unix-static.yml as follows:
-#
-#   * Does not build rav1e, SVT-AV1 nor libgav1.
-
-name: CI Unix Shared Local
-on: [push, pull_request]
+name: CI macOS Shared Local
+on:
+  push:
+    branches:
+      - main
 
 permissions:
   contents: read
@@ -15,33 +14,22 @@
 
 jobs:
   build-shared-local:
-    runs-on: ${{ matrix.os }}
+    runs-on: macos-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest, macos-latest]
         libyuv: [OFF, LOCAL]
         include:
           - runs-on: ubuntu-latest
             compiler: gcc
             gcc: 14
 
-    name: build-shared-local (${{ matrix.os }}, libyuv ${{ matrix.libyuv }})
+    name: build-shared-local (macos, libyuv ${{ matrix.libyuv }})
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           persist-credentials: false
-      - uses: ./.github/actions/setup-linux
-        if: runner.os == 'Linux'
-        with:
-          codec-aom: "LOCAL"
-          codec-dav1d: "LOCAL"
-          gcc-version: ${{ matrix.gcc }}
-          libjpeg-turbo: "SYSTEM"
-          libxml2: "LOCAL"
-          libyuv: ${{ matrix.libyuv }}
-          zlibpng: "SYSTEM"
       - uses: ./.github/actions/setup-macos
         if: runner.os == 'macOS'
         with:
diff --git a/.github/workflows/ci-unix-static.yml b/.github/workflows/ci-macos-static.yml
similarity index 77%
copy from .github/workflows/ci-unix-static.yml
copy to .github/workflows/ci-macos-static.yml
index 10d3182..053e5f1 100644
--- a/.github/workflows/ci-unix-static.yml
+++ b/.github/workflows/ci-macos-static.yml
@@ -1,7 +1,8 @@
-name: CI Unix Static
+name: CI macOS Static
 on:
   push:
-  pull_request:
+    branches:
+      - main
     paths:
       - ".github/actions/**"
       - ".github/workflows/ci-unix-static.yml"
@@ -18,36 +19,20 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-static:
-    runs-on: ${{ matrix.os }}
+  build-static-local:
+    runs-on: macos-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest, macos-latest]
         build-type: [Release, Debug]
-        include:
-          - runs-on: ubuntu-latest
-            compiler: gcc
-            gcc: 14
+
+    name: build-static-local (macos, ${{ matrix.build-type }})
 
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           persist-credentials: false
-      - uses: ./.github/actions/setup-linux
-        if: runner.os == 'Linux'
-        with:
-          codec-aom: "LOCAL"
-          codec-dav1d: "LOCAL"
-          codec-rav1e: "LOCAL"
-          codec-svt: "LOCAL"
-          gcc-version: ${{ matrix.gcc }}
-          libjpeg-turbo: "SYSTEM"
-          libxml2: "LOCAL"
-          libyuv: "LOCAL"
-          zlibpng: "SYSTEM"
       - uses: ./.github/actions/setup-macos
-        if: runner.os == 'macOS'
         with:
           codec-aom: "LOCAL"
           codec-dav1d: "LOCAL"
@@ -77,7 +62,6 @@
         run: ctest -j $(getconf _NPROCESSORS_ONLN) --output-on-failure
 
       - name: Set CC on macOS
-        if: ${{ runner.os == 'macOS' }}
         run:
           echo "CC=cc" >> $GITHUB_ENV
         shell: bash
diff --git a/.github/workflows/ci-mingw.yml b/.github/workflows/ci-mingw.yml
index 93c6762..77f4cfa 100644
--- a/.github/workflows/ci-mingw.yml
+++ b/.github/workflows/ci-mingw.yml
@@ -22,6 +22,8 @@
           - ucrt64
           - clang64
 
+    name: build-mingw
+
     defaults:
       run:
         shell: msys2 {0}
diff --git a/.github/workflows/ci-windows-artifacts.yml b/.github/workflows/ci-windows-artifacts.yml
index 63c5861..e5f339d 100644
--- a/.github/workflows/ci-windows-artifacts.yml
+++ b/.github/workflows/ci-windows-artifacts.yml
@@ -19,6 +19,8 @@
       matrix:
         os: [windows-latest]
 
+    name: build-windows-artifacts
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-windows-installed.yml b/.github/workflows/ci-windows-installed.yml
index 96f7c8d..34cbeac 100644
--- a/.github/workflows/ci-windows-installed.yml
+++ b/.github/workflows/ci-windows-installed.yml
@@ -15,13 +15,15 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-windows-installed:
+  build-static-installed:
     runs-on: windows-latest
     strategy:
       fail-fast: false
       matrix:
         compiler: [msvc, clang-cl]
 
+    name: build-static-installed (windows, ${{ matrix.compiler }})
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-windows-shared-local.yml b/.github/workflows/ci-windows-shared-local.yml
index 4a090f3..8b3a6f3 100644
--- a/.github/workflows/ci-windows-shared-local.yml
+++ b/.github/workflows/ci-windows-shared-local.yml
@@ -20,13 +20,15 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-windows-shared-local:
+  build-shared-local:
     runs-on: windows-latest
     strategy:
       fail-fast: false
       matrix:
         compiler: [msvc, clang-cl]
 
+    name: build-shared-local (windows, ${{ matrix.compiler }})
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows-static-local.yml
similarity index 87%
rename from .github/workflows/ci-windows.yml
rename to .github/workflows/ci-windows-static-local.yml
index c4277bd..a64e77b 100644
--- a/.github/workflows/ci-windows.yml
+++ b/.github/workflows/ci-windows-static-local.yml
@@ -1,13 +1,4 @@
-# This is a copy of ci-unix-static.yml for Windows. It differs from ci-unix-static.yml as follows:
-#
-#   * The os matrix consists of windows-latest only.
-#   * Installs Visual Studio in the os image.
-#   * Runs ext/*.cmd as Windows batch files rather than using bash. This is
-#     important for ext/svt.cmd, to prevent it from running ext/svt.sh.
-#   * Builds with local libjpeg (-DAVIF_JPEG=LOCAL).
-#   * Builds with local zlib and libpng (-DAVIF_ZLIBPNG=LOCAL).
-
-name: CI Windows
+name: CI Windows Static Local
 on:
   push:
   pull_request:
@@ -27,14 +18,15 @@
   cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
 
 jobs:
-  build-windows:
-    runs-on: ${{ matrix.os }}
+  build-static-local:
+    runs-on: windows-latest
     strategy:
       fail-fast: false
       matrix:
-        os: [windows-latest]
         generator: ["-G Ninja", ""]
 
+    name: build-static-local (windows, cmake ${{ matrix.generator }})
+
     steps:
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with: