From 3d6cba5b20a169a7021420aec4bc905d866f52b1 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sun, 26 Jul 2026 09:05:55 +0200 Subject: [PATCH 1/3] ci: stop freezing the conan and ccache caches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `actions/cache` never overwrites an existing key, so a key that never varies is written once and then frozen: every later run restores that first snapshot and rebuilds whatever it is missing from source. Measured on run 30175816272, the ubuntu-clang build spends 13 of its 22 minutes in `conan install`, rebuilding 14 dependencies (pdf2htmlex, poppler, cairo, fontforge, wvware, ...) from source — on every single run. No job in that run logs a cache save. The jni workflow, whose key happens to be young enough to hold a complete cache, does the same `conan install` in under a minute. Two jobs sharing one key made it worse: `build` and `build-test-downstream` both wrote `conan-ubuntu-24.04-clang-18-r1` with different dependency sets, so whichever landed first left the other rebuilding forever. `CACHE_FLAVOR` now separates them. Key the conan cache on what determines its content (odr-index revision + conanfile + profile) so it is rewritten exactly when dependencies change, and give ccache a per-run key restored by prefix so it can grow. ccache is saved only on the default branch — branch-scoped entries are invisible to other branches and would only churn the 10 GB repo quota, which is already full (10.74 GB across 24 entries). Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01LDqWDNJQNroJPH9j5BfaPv --- .github/workflows/build_test.yml | 64 ++++++++++++++++++++++++++------ .github/workflows/python.yml | 29 +++++++++++---- 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 117ae0ab4..f8415672d 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -6,6 +6,18 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true +# Cache keys, in short: `actions/cache` never overwrites an existing key, so a +# key that stays the same forever is written exactly once and then frozen — +# every later run restores that first snapshot and rebuilds whatever is missing +# from source. Both caches therefore vary their key: +# * conan — keyed on what determines its content (recipes + profile), so it is +# rewritten precisely when the dependencies change. +# * ccache — keyed per run and restored via prefix, so it keeps growing. Only +# the default branch writes it; branch-scoped entries are invisible to other +# branches and would just churn the 10 GB repo quota. +# `CACHE_FLAVOR` separates jobs that resolve a *different* dependency set for the +# same profile — without it they overwrite each other and both keep rebuilding. +# The `*_KEY_SUFFIX` variables stay as a manual "throw it all away" knob. env: CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_MAXSIZE: 1G @@ -16,6 +28,8 @@ env: jobs: build: runs-on: ${{ matrix.os }} + env: + CACHE_FLAVOR: main strategy: fail-fast: false matrix: @@ -54,26 +68,30 @@ jobs: if: startsWith(matrix.host_profile, 'android') run: yes | ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install 'ndk;${{ matrix.ndk_version }}' + - name: conan cache key + shell: bash + run: echo "CONAN_CACHE_KEY=$(git rev-parse HEAD:conan-odr-index)-${{ hashFiles('conanfile.py', '.github/config/conan/**') }}" >> "$GITHUB_ENV" + - name: cache conan uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ${{ env.CONAN_HOME }} - key: conan-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }} + key: conan-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }}-${{ env.CONAN_CACHE_KEY }} restore-keys: | - conan-${{ matrix.host_profile }}- + conan-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }}- - name: export conan-odr-index run: python conan-odr-index/scripts/conan_export_all_packages.py --selection-config conan-odr-index/defaults.yaml - name: conan config run: conan config install .github/config/conan - - name: cache ccache - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + - name: restore ccache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ${{ env.CCACHE_DIR }} - key: ccache-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }} + key: ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.run_id }} restore-keys: | - ccache-${{ matrix.host_profile }}- + ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}- - name: conan install run: > @@ -113,6 +131,13 @@ jobs: - name: build run: cmake --build build --config Release + - name: save ccache + if: github.ref == 'refs/heads/main' + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.run_id }} + - name: install run: cmake --build build --target install --config Release @@ -267,6 +292,10 @@ jobs: build-test-downstream: runs-on: ${{ matrix.os }} + # Exports the full odr-index (no `--selection-config`) and resolves through + # `conan.lock`, so its dependency set differs from the `build` job's. + env: + CACHE_FLAVOR: downstream strategy: fail-fast: false matrix: @@ -300,13 +329,17 @@ jobs: if: startsWith(matrix.host_profile, 'android') run: yes | ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install 'ndk;${{ matrix.ndk_version }}' + - name: conan cache key + shell: bash + run: echo "CONAN_CACHE_KEY=$(git rev-parse HEAD:conan-odr-index)-${{ hashFiles('conanfile.py', 'conan.lock', '.github/config/conan/**') }}" >> "$GITHUB_ENV" + - name: cache conan uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ${{ env.CONAN_HOME }} - key: conan-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }} + key: conan-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }}-${{ env.CONAN_CACHE_KEY }} restore-keys: | - conan-${{ matrix.host_profile }}- + conan-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }}- - name: export conan-odr-index run: python conan-odr-index/scripts/conan_export_all_packages.py @@ -316,13 +349,13 @@ jobs: - name: conan odrcore run: conan export . --name odrcore --version 0.0.0 - - name: cache ccache - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + - name: restore ccache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ${{ env.CCACHE_DIR }} - key: ccache-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }} + key: ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.run_id }} restore-keys: | - ccache-${{ matrix.host_profile }}- + ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}- - name: conan install run: > @@ -350,6 +383,13 @@ jobs: - name: build run: cmake --build test/downstream/build --config Release + - name: save ccache + if: github.ref == 'refs/heads/main' + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.run_id }} + - name: run if: matrix.build_profile == matrix.host_profile && (runner.os == 'Linux' || runner.os == 'macOS') run: test/downstream/build/odr-test-downstream diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 538dca833..861b377d9 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -10,6 +10,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true +# See the cache-key comment in `build_test.yml` for why the keys look like this. env: CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_MAXSIZE: 1G @@ -116,6 +117,10 @@ jobs: wheels: runs-on: ${{ matrix.os }} + # Builds the reduced dependency set that `pyproject.toml` pins (no + # pdf2htmlEX/wvWare/libmagic), so it cannot share a cache with `build_test`. + env: + CACHE_FLAVOR: wheel strategy: fail-fast: false matrix: @@ -151,27 +156,30 @@ jobs: - name: install python dependencies run: pip install conan build pytest + - name: conan cache key + shell: bash + run: echo "CONAN_CACHE_KEY=$(git rev-parse HEAD:conan-odr-index)-${{ hashFiles('conanfile.py', 'pyproject.toml', '.github/config/conan/**') }}" >> "$GITHUB_ENV" + - name: cache conan uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ${{ env.CONAN_HOME }} - key: conan-wheel-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }} + key: conan-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }}-${{ env.CONAN_CACHE_KEY }} restore-keys: | - conan-wheel-${{ matrix.host_profile }}- + conan-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }}- - name: export conan-odr-index run: python conan-odr-index/scripts/conan_export_all_packages.py --selection-config conan-odr-index/defaults.yaml - name: conan config run: conan config install .github/config/conan - - name: cache ccache - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + - name: restore ccache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ${{ env.CCACHE_DIR }} - key: ccache-wheel-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }} + key: ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.run_id }} restore-keys: | - ccache-wheel-${{ matrix.host_profile }}- - ccache-${{ matrix.host_profile }}- + ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}- # Match the dependency set that pyproject.toml enables (no pdf2htmlEX, # wvWare, libmagic — their runtime data cannot ship inside the wheel). @@ -191,6 +199,13 @@ jobs: env: CMAKE_ARGS: -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/conan_toolchain.cmake + - name: save ccache + if: github.ref == 'refs/heads/main' + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.run_id }} + # PyPI rejects plain `linux_*` platform tags; auditwheel grafts the wheel # onto the matching manylinux tag (the conan deps are linked statically, # so there should be no external libraries to vendor). From bd85f22c9545dfae769ad451a4356c6087ec2c15 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sun, 26 Jul 2026 09:08:46 +0200 Subject: [PATCH 2/3] ci: build the bindings in the central build job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The JNI and Python bindings each had their own workflow that reconfigured and rebuilt the core from scratch for ubuntu-clang and macos-26 — the two profiles `build_test` already covers. Per push that was three independent resolutions of the same dependency graph and three compiles of the same library, plus three sets of caches competing for the repo quota. `ODR_CLI`/`ODR_TEST`/`ODR_JNI`/`ODR_PYTHON` are independent subdirectory guards and `with_jni`/`with_python` only widen the conan graph, so one configure produces all of it. The matrix gains a `bindings` flag; the two suites run in-job via ctest because they take seconds and an artifact round-trip would cost more than it saves. `wheels` stays where it is: it deliberately builds the reduced dependency set that `pyproject.toml` pins (no pdf2htmlEX/wvWare/libmagic, whose runtime data cannot ship inside a wheel), so its binary cannot be the one `build_test` produces. `maven` is unaffected — the jar is classes-only and needs no native artifact. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01LDqWDNJQNroJPH9j5BfaPv --- .github/workflows/build_test.yml | 31 ++++++++-- .github/workflows/jni.yml | 102 ------------------------------- .github/workflows/python.yml | 87 ++------------------------ 3 files changed, 32 insertions(+), 188 deletions(-) delete mode 100644 .github/workflows/jni.yml diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index f8415672d..a9b3bcf91 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -26,18 +26,22 @@ env: CONAN_KEY_SUFFIX: r1 jobs: + # Builds the core once per profile and, where `bindings` is set, the JNI and + # Python bindings out of the same configure. They used to live in their own + # workflows, which meant compiling the core and resolving its dependencies + # three times over for the same two profiles. build: runs-on: ${{ matrix.os }} env: - CACHE_FLAVOR: main + CACHE_FLAVOR: main${{ matrix.bindings && '-bindings' || '' }} strategy: fail-fast: false matrix: include: - - { os: ubuntu-24.04, build_profile: ubuntu-24.04-clang-18, host_profile: ubuntu-24.04-clang-18 } + - { os: ubuntu-24.04, build_profile: ubuntu-24.04-clang-18, host_profile: ubuntu-24.04-clang-18, bindings: true } - { os: ubuntu-24.04, build_profile: ubuntu-24.04-gcc-14, host_profile: ubuntu-24.04-gcc-14 } - { os: macos-15, build_profile: macos-15-armv8-clang-14, host_profile: macos-15-armv8-clang-14 } - - { os: macos-26, build_profile: macos-26-armv8-clang-14, host_profile: macos-26-armv8-clang-14 } + - { os: macos-26, build_profile: macos-26-armv8-clang-14, host_profile: macos-26-armv8-clang-14, bindings: true } - { os: windows-2022, build_profile: windows-2022-msvc-1940, host_profile: windows-2022-msvc-1940 } - { os: ubuntu-24.04, build_profile: ubuntu-24.04-clang-18, host_profile: android-35-x86_64, ndk_version: 28.1.13356709 } steps: @@ -57,12 +61,19 @@ jobs: brew install ccache ccache -V + - name: setup java + if: matrix.bindings + uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 # v5 + with: + distribution: temurin + java-version: 21 + - name: setup python 3.14 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: 3.14 - name: install python dependencies - run: pip install conan + run: pip install conan ${{ matrix.bindings && 'pytest' || '' }} - name: install NDK if: startsWith(matrix.host_profile, 'android') @@ -96,6 +107,7 @@ jobs: - name: conan install run: > conan install . + ${{ matrix.bindings && '-o "&:with_jni=True" -o "&:with_python=True"' || '' }} --profile:host '${{ matrix.host_profile }}' --profile:build '${{ matrix.build_profile }}' --build missing @@ -114,6 +126,7 @@ jobs: -DODR_WITH_WVWARE=ON -DODR_WITH_LIBMAGIC=ON -DODR_BUNDLE_ASSETS=ON + ${{ matrix.bindings && '-DODR_JNI=ON -DODR_PYTHON=ON' || '' }} - name: cmake if: runner.os == 'Windows' @@ -138,6 +151,16 @@ jobs: path: ${{ env.CCACHE_DIR }} key: ccache-${{ env.CACHE_FLAVOR }}-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.run_id }} + # Both suites run in seconds, so they stay in this job rather than paying + # an artifact round-trip. The heavy `odr_test` still runs in `test`, which + # needs firefox and the reference-output submodule. + - name: junit + if: matrix.bindings + run: ctest --test-dir build/jni --output-on-failure + - name: pytest + if: matrix.bindings + run: ctest --test-dir build/python --output-on-failure + - name: install run: cmake --build build --target install --config Release diff --git a/.github/workflows/jni.yml b/.github/workflows/jni.yml deleted file mode 100644 index d0ba5c69d..000000000 --- a/.github/workflows/jni.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: jni - -on: - push: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -env: - CCACHE_DIR: ${{ github.workspace }}/.ccache - CCACHE_MAXSIZE: 1G - CCACHE_KEY_SUFFIX: r1 - CONAN_HOME: ${{ github.workspace }}/.conan2 - CONAN_KEY_SUFFIX: r1 - -jobs: - build-test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - { os: ubuntu-24.04, build_profile: ubuntu-24.04-clang-18, host_profile: ubuntu-24.04-clang-18 } - - { os: macos-26, build_profile: macos-26-armv8-clang-14, host_profile: macos-26-armv8-clang-14 } - steps: - - name: checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - name: checkout conan-odr-index - run: git submodule update --init --depth 1 conan-odr-index - - - name: ubuntu install ccache - if: runner.os == 'Linux' - run: | - sudo apt install ccache - ccache -V - - name: macos install ccache - if: runner.os == 'macOS' - run: | - brew install ccache - ccache -V - - - name: setup java - uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 # v5 - with: - distribution: temurin - java-version: 21 - - - name: setup python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 - with: - python-version: 3.14 - - name: install python dependencies - run: pip install conan - - - name: cache conan - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ${{ env.CONAN_HOME }} - key: conan-jni-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }} - restore-keys: | - conan-jni-${{ matrix.host_profile }}- - conan-${{ matrix.host_profile }}- - - - name: export conan-odr-index - run: python conan-odr-index/scripts/conan_export_all_packages.py --selection-config conan-odr-index/defaults.yaml - - name: conan config - run: conan config install .github/config/conan - - - name: cache ccache - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-jni-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }} - restore-keys: | - ccache-jni-${{ matrix.host_profile }}- - ccache-${{ matrix.host_profile }}- - - - name: conan install - run: > - conan install . - -o '&:with_jni=True' - --profile:host '${{ matrix.host_profile }}' - --profile:build '${{ matrix.build_profile }}' - --build missing - - - name: cmake - run: > - cmake -B build -S . - -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_CXX_FLAGS="-Werror" - -DODR_JNI=ON - -DODR_CLI=OFF - -DODR_TEST=ON - - - name: build - run: cmake --build build --target odr_jni odr_java odr_java_tests --config Release - - - name: junit - run: ctest --test-dir build/jni --output-on-failure diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 861b377d9..51c9f4d85 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -35,86 +35,9 @@ jobs: - name: check python formatting run: black --check --diff python - build-test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - { os: ubuntu-24.04, build_profile: ubuntu-24.04-clang-18, host_profile: ubuntu-24.04-clang-18 } - - { os: macos-26, build_profile: macos-26-armv8-clang-14, host_profile: macos-26-armv8-clang-14 } - steps: - - name: checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - name: checkout conan-odr-index - run: git submodule update --init --depth 1 conan-odr-index - - - name: ubuntu install ccache - if: runner.os == 'Linux' - run: | - sudo apt install ccache - ccache -V - - name: macos install ccache - if: runner.os == 'macOS' - run: | - brew install ccache - ccache -V - - - name: setup python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 - with: - python-version: 3.14 - - name: install python dependencies - run: pip install conan pytest - - - name: cache conan - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ${{ env.CONAN_HOME }} - key: conan-python-${{ matrix.host_profile }}-${{ env.CONAN_KEY_SUFFIX }} - restore-keys: | - conan-python-${{ matrix.host_profile }}- - conan-${{ matrix.host_profile }}- - - - name: export conan-odr-index - run: python conan-odr-index/scripts/conan_export_all_packages.py --selection-config conan-odr-index/defaults.yaml - - name: conan config - run: conan config install .github/config/conan - - - name: cache ccache - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-python-${{ matrix.host_profile }}-${{ env.CCACHE_KEY_SUFFIX }} - restore-keys: | - ccache-python-${{ matrix.host_profile }}- - ccache-${{ matrix.host_profile }}- - - - name: conan install - run: > - conan install . - -o '&:with_python=True' - --profile:host '${{ matrix.host_profile }}' - --profile:build '${{ matrix.build_profile }}' - --build missing - - - name: cmake - run: > - cmake -B build -S . - -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_CXX_FLAGS="-Werror" - -DODR_PYTHON=ON - -DODR_CLI=OFF - -DODR_TEST=OFF - - - name: build - run: cmake --build build --target pyodr_core --config Release - - - name: pytest - run: PYTHONPATH=build/python python -m pytest python/tests -v - + # The bindings themselves are built and tested by the `build` job in + # `build_test.yml`, out of the same configure as the core. What stays here is + # everything that needs the wheel's own, reduced dependency set. wheels: runs-on: ${{ matrix.os }} # Builds the reduced dependency set that `pyproject.toml` pins (no @@ -251,7 +174,7 @@ jobs: if-no-files-found: error publish: - needs: [build-test, wheels, sdist] + needs: [wheels, sdist] runs-on: ubuntu-24.04 if: github.event_name == 'release' && github.event.action == 'published' permissions: @@ -274,7 +197,7 @@ jobs: # conan-generated toolchain plus the conan-odr-index recipes, see # python/README.md); it is published for completeness. pypi: - needs: [build-test, wheels, sdist] + needs: [wheels, sdist] runs-on: ubuntu-24.04 if: github.event_name == 'release' && github.event.action == 'published' environment: pypi From ad2a2cc7cb6085433fc7400c040e866e3c1b7a6c Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sun, 26 Jul 2026 09:13:47 +0200 Subject: [PATCH 3/3] ci: drop the dead NDK step from build-test-downstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That job's matrix only ever contains ubuntu-24.04-clang-18, so the step's `startsWith(matrix.host_profile, 'android')` guard never fires and the `matrix.ndk_version` it interpolates is not defined anywhere — actionlint flags the reference as an error. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01LDqWDNJQNroJPH9j5BfaPv --- .github/workflows/build_test.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index a9b3bcf91..49bde477a 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -348,10 +348,6 @@ jobs: - name: install python dependencies run: pip install conan - - name: install NDK - if: startsWith(matrix.host_profile, 'android') - run: yes | ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install 'ndk;${{ matrix.ndk_version }}' - - name: conan cache key shell: bash run: echo "CONAN_CACHE_KEY=$(git rev-parse HEAD:conan-odr-index)-${{ hashFiles('conanfile.py', 'conan.lock', '.github/config/conan/**') }}" >> "$GITHUB_ENV"