From 9177edfe4aa2c24cfb4bddc975096d77f2cae4b1 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 17:05:17 +0300 Subject: [PATCH 01/28] ci: target Incredibuild Hosted Build Runner for all Linux jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces every Linux GitHub Actions runner label (ubuntu-*, depot-ubuntu-*, github-ubuntu-*) with `incredibuild-runner` across all 26 workflows (93 jobs total). macOS, Windows, and CodSpeed runners are intentionally left alone — Incredibuild Hosted Build Runner is Linux-only. The Incredibuild app is installed on the Incredibuild-RND org and runners are registered for this fork. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/bench.yml | 4 +-- .github/workflows/build-dev-binaries.yml | 14 ++++---- .github/workflows/build-docker.yml | 8 ++--- .github/workflows/build-release-binaries.yml | 18 +++++----- .github/workflows/check-docs.yml | 2 +- .github/workflows/check-fmt.yml | 6 ++-- .github/workflows/check-generated-files.yml | 2 +- .github/workflows/check-lint.yml | 16 ++++----- .github/workflows/check-publish.yml | 2 +- .github/workflows/check-release.yml | 2 +- .github/workflows/check-zizmor.yml | 2 +- .github/workflows/ci.yml | 6 ++-- .github/workflows/publish-crates.yml | 2 +- .github/workflows/publish-docs.yml | 2 +- .github/workflows/publish-mirror.yml | 2 +- .github/workflows/publish-pypi.yml | 4 +-- .github/workflows/publish-versions.yml | 2 +- .github/workflows/release-prepare.yml | 2 +- .github/workflows/release.yml | 12 +++---- .github/workflows/sync-python-releases.yml | 2 +- .github/workflows/test-ecosystem.yml | 2 +- .github/workflows/test-integration.yml | 28 +++++++-------- .github/workflows/test-smoke.yml | 6 ++-- .github/workflows/test-system.yml | 34 +++++++++---------- .../workflows/test-windows-trampolines.yml | 4 +-- .github/workflows/test.yml | 2 +- 26 files changed, 93 insertions(+), 93 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index fe264ed00915e..4ebbd8faed121 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -18,7 +18,7 @@ jobs: benchmarks-walltime-build: name: "walltime build" # codspeed-macro doesn't support Ubuntu 24.04 yet - runs-on: depot-ubuntu-22.04-arm-4 + runs-on: incredibuild-runner if: ${{ github.repository == 'astral-sh/uv' }} timeout-minutes: 20 steps: @@ -96,7 +96,7 @@ jobs: benchmarks-simulated: name: "simulated" - runs-on: depot-ubuntu-24.04-4 + runs-on: incredibuild-runner if: ${{ github.repository == 'astral-sh/uv' }} timeout-minutes: 20 steps: diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index b2519636c038a..c40b1e17ad9d1 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -18,7 +18,7 @@ jobs: build-binary-linux-libc: name: "linux libc" timeout-minutes: 10 - runs-on: github-ubuntu-24.04-x86_64-8 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -46,7 +46,7 @@ jobs: build-binary-linux-aarch64: name: "linux aarch64" timeout-minutes: 10 - runs-on: github-ubuntu-24.04-aarch64-4 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -74,7 +74,7 @@ jobs: build-binary-linux-armv7-gnueabihf: name: "linux armv7 gnueabihf" timeout-minutes: 15 - runs-on: github-ubuntu-24.04-x86_64-8 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -110,7 +110,7 @@ jobs: build-binary-linux-musl: name: "linux musl" timeout-minutes: 10 - runs-on: github-ubuntu-24.04-x86_64-8 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -260,7 +260,7 @@ jobs: build-binary-msrv: name: "msrv" - runs-on: github-ubuntu-24.04-x86_64-8 + runs-on: incredibuild-runner timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -288,7 +288,7 @@ jobs: build-binary-android-aarch64: name: "android aarch64" timeout-minutes: 10 - runs-on: github-ubuntu-24.04-x86_64-8 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -338,7 +338,7 @@ jobs: build-binary-freebsd: name: "freebsd" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index c80be5d33533f..66c59d110ef1a 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -38,7 +38,7 @@ permissions: {} jobs: docker-plan: name: plan - runs-on: ubuntu-latest + runs-on: incredibuild-runner timeout-minutes: 2 outputs: login: ${{ steps.plan.outputs.login }} @@ -128,7 +128,7 @@ jobs: name: ${{ needs.docker-plan.outputs.action }} uv needs: - docker-plan - runs-on: ubuntu-latest + runs-on: incredibuild-runner timeout-minutes: 20 permissions: contents: read @@ -225,7 +225,7 @@ jobs: docker-publish-extra: name: ${{ needs.docker-plan.outputs.action }} ${{ matrix.image-mapping }} - runs-on: ubuntu-latest + runs-on: incredibuild-runner timeout-minutes: 5 environment: name: ${{ needs.docker-plan.outputs.push-version == 'true' && 'release' || (needs.docker-plan.outputs.push == 'true' && 'release-test' || '') }} @@ -396,7 +396,7 @@ jobs: # Annotate the base image docker-annotate-base: name: annotate uv - runs-on: ubuntu-latest + runs-on: incredibuild-runner timeout-minutes: 2 permissions: contents: read diff --git a/.github/workflows/build-release-binaries.yml b/.github/workflows/build-release-binaries.yml index 7ebc949fa772b..cef26bfc30634 100644 --- a/.github/workflows/build-release-binaries.yml +++ b/.github/workflows/build-release-binaries.yml @@ -32,7 +32,7 @@ permissions: {} jobs: sdist: name: sdist - runs-on: depot-ubuntu-24.04-4 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -331,7 +331,7 @@ jobs: linux: name: ${{ matrix.target }} - runs-on: depot-ubuntu-latest-4 + runs-on: incredibuild-runner strategy: matrix: include: @@ -447,7 +447,7 @@ jobs: linux-arm: name: ${{ matrix.platform.target }} - runs-on: depot-ubuntu-24.04-8 + runs-on: incredibuild-runner timeout-minutes: 30 strategy: matrix: @@ -578,7 +578,7 @@ jobs: linux-s390x: name: ${{ matrix.platform.target }} timeout-minutes: 30 - runs-on: depot-ubuntu-latest-4 + runs-on: incredibuild-runner strategy: matrix: platform: @@ -699,7 +699,7 @@ jobs: # Like `linux-arm`, but install the `gcc-powerpc64-linux-gnu` package. linux-powerpc: name: ${{ matrix.platform.target }} - runs-on: depot-ubuntu-24.04-4 + runs-on: incredibuild-runner strategy: matrix: platform: @@ -810,7 +810,7 @@ jobs: linux-riscv64: name: ${{ matrix.platform.target }} timeout-minutes: 30 - runs-on: depot-ubuntu-latest-4 + runs-on: incredibuild-runner strategy: matrix: platform: @@ -927,7 +927,7 @@ jobs: musllinux: name: ${{ matrix.target }} - runs-on: depot-ubuntu-24.04-4 + runs-on: incredibuild-runner strategy: matrix: target: @@ -1030,7 +1030,7 @@ jobs: musllinux-cross: name: ${{ matrix.platform.target }} - runs-on: depot-ubuntu-24.04-8 + runs-on: incredibuild-runner env: CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_MUSL_RUSTFLAGS: "-C target-feature=+crt-static" strategy: @@ -1194,7 +1194,7 @@ jobs: check-wheels: name: "Check wheel contents" - runs-on: ubuntu-slim + runs-on: incredibuild-runner needs: - macos-x86_64 - macos-aarch64 diff --git a/.github/workflows/check-docs.yml b/.github/workflows/check-docs.yml index 605f2235a9951..09e26c21239f8 100644 --- a/.github/workflows/check-docs.yml +++ b/.github/workflows/check-docs.yml @@ -7,7 +7,7 @@ jobs: docs: timeout-minutes: 10 name: "mkdocs" - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/check-fmt.yml b/.github/workflows/check-fmt.yml index 17102b4447801..567724139db1b 100644 --- a/.github/workflows/check-fmt.yml +++ b/.github/workflows/check-fmt.yml @@ -6,7 +6,7 @@ permissions: {} jobs: rust: timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -17,7 +17,7 @@ jobs: prettier: timeout-minutes: 10 - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -26,7 +26,7 @@ jobs: python: timeout-minutes: 10 - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/check-generated-files.yml b/.github/workflows/check-generated-files.yml index cb23413af34f4..cc5cc03c2192f 100644 --- a/.github/workflows/check-generated-files.yml +++ b/.github/workflows/check-generated-files.yml @@ -20,7 +20,7 @@ env: jobs: cargo-dev-generate-all: timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner name: "cargo dev generate-all" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index c16c465386c92..0e735061978ba 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -20,7 +20,7 @@ env: jobs: ruff: timeout-minutes: 10 - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -33,7 +33,7 @@ jobs: ty: timeout-minutes: 10 - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -51,7 +51,7 @@ jobs: shellcheck: timeout-minutes: 10 - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -67,7 +67,7 @@ jobs: validate-pyproject: timeout-minutes: 10 - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -80,7 +80,7 @@ jobs: readme: timeout-minutes: 10 - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -94,7 +94,7 @@ jobs: name: "clippy on linux" timeout-minutes: 10 if: ${{ inputs.code-changed == 'true' || github.ref == 'refs/heads/main' }} - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -145,7 +145,7 @@ jobs: shear: name: "cargo shear" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -157,7 +157,7 @@ jobs: - run: cargo shear --deny-warnings typos: - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index f8fb1302f8216..ddd103b2ae636 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -12,7 +12,7 @@ env: jobs: cargo-publish-dry-run: timeout-minutes: 20 - runs-on: depot-ubuntu-24.04-8 + runs-on: incredibuild-runner name: "cargo publish dry-run" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/check-release.yml b/.github/workflows/check-release.yml index aafcf3d290eef..bc965eca27ca3 100644 --- a/.github/workflows/check-release.yml +++ b/.github/workflows/check-release.yml @@ -8,7 +8,7 @@ env: jobs: dist-plan: name: "dist plan" - runs-on: ubuntu-latest + runs-on: incredibuild-runner env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: diff --git a/.github/workflows/check-zizmor.yml b/.github/workflows/check-zizmor.yml index eef8fa85737b0..871235dddc007 100644 --- a/.github/workflows/check-zizmor.yml +++ b/.github/workflows/check-zizmor.yml @@ -5,7 +5,7 @@ permissions: {} jobs: zizmor: - runs-on: ubuntu-latest + runs-on: incredibuild-runner permissions: security-events: write steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4e7ed8a95ccf..9e24423a776d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ concurrency: jobs: plan: - runs-on: depot-ubuntu-24.04 + runs-on: incredibuild-runner outputs: test-code: ${{ steps.plan.outputs.test_code }} check-schema: ${{ steps.plan.outputs.check_schema }} @@ -275,7 +275,7 @@ jobs: needs: - plan - build-dev-binaries - runs-on: ubuntu-latest + runs-on: incredibuild-runner # Only the main repository is a trusted publisher if: ${{ github.repository == 'astral-sh/uv' && github.event.pull_request.head.repo.fork != true && needs.plan.outputs.test-publish == 'true' }} environment: @@ -406,7 +406,7 @@ jobs: - check-generated-files - test - build-dev-binaries - runs-on: ubuntu-slim + runs-on: incredibuild-runner steps: - name: "Check required jobs passed" run: | diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml index 9c0ad1c155b09..cb999bc8934b1 100644 --- a/.github/workflows/publish-crates.yml +++ b/.github/workflows/publish-crates.yml @@ -14,7 +14,7 @@ on: jobs: crates-publish-uv: name: Upload uv to crates.io - runs-on: ubuntu-latest + runs-on: incredibuild-runner environment: name: release permissions: diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index bbed92921dea5..98b0c257015d2 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -23,7 +23,7 @@ jobs: mkdocs: environment: name: release - runs-on: ubuntu-latest + runs-on: incredibuild-runner env: VERSION: ${{ (inputs.plan != '' && fromJson(inputs.plan).announcement_tag) || inputs.ref }} steps: diff --git a/.github/workflows/publish-mirror.yml b/.github/workflows/publish-mirror.yml index b46571687d9ba..b2de5c4d5d826 100644 --- a/.github/workflows/publish-mirror.yml +++ b/.github/workflows/publish-mirror.yml @@ -14,7 +14,7 @@ permissions: {} jobs: publish-mirror: - runs-on: ubuntu-latest + runs-on: incredibuild-runner environment: name: release env: diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 85c915e352b32..998626db2d211 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -14,7 +14,7 @@ on: jobs: pypi-publish-uv: name: Upload uv to PyPI - runs-on: ubuntu-latest + runs-on: incredibuild-runner environment: name: release permissions: @@ -32,7 +32,7 @@ jobs: pypi-publish-uv-build: name: Upload uv-build to PyPI - runs-on: ubuntu-latest + runs-on: incredibuild-runner environment: name: release permissions: diff --git a/.github/workflows/publish-versions.yml b/.github/workflows/publish-versions.yml index 1e4f51f2a614f..0d239a9a28d2a 100644 --- a/.github/workflows/publish-versions.yml +++ b/.github/workflows/publish-versions.yml @@ -15,7 +15,7 @@ permissions: {} jobs: publish-versions: - runs-on: ubuntu-latest + runs-on: incredibuild-runner environment: name: release env: diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml index 86b54987dec15..bf2133e23deeb 100644 --- a/.github/workflows/release-prepare.yml +++ b/.github/workflows/release-prepare.yml @@ -18,7 +18,7 @@ permissions: {} jobs: release: if: github.repository == 'astral-sh/uv' - runs-on: ubuntu-latest + runs-on: incredibuild-runner permissions: contents: write pull-requests: write diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 718ed13e9715e..9c458d91e3584 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,7 +56,7 @@ jobs: # N.B. This name should not change, it is used for downstream checks. name: release-gate if: ${{ inputs.tag != 'dry-run' }} - runs-on: ubuntu-latest + runs-on: incredibuild-runner # This environment requires a 2-factor approval, i.e., the workflow must be approved by another # team member. GitHub fires approval events on every job that deploys to an environment, so we # have a dedicated environment for this purpose instead of using the `release` environment. @@ -70,7 +70,7 @@ jobs: # Run 'dist plan' (or host) to determine what tasks we need to do plan: - runs-on: "depot-ubuntu-latest-4" + runs-on: "incredibuild-runner" outputs: val: ${{ steps.plan.outputs.manifest }} tag: ${{ (inputs.tag != 'dry-run' && inputs.tag) || '' }} @@ -141,7 +141,7 @@ jobs: - plan - custom-build-release-binaries if: ${{ needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload' || inputs.tag == 'dry-run' }} - runs-on: "depot-ubuntu-latest-4" + runs-on: "incredibuild-runner" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: @@ -181,7 +181,7 @@ jobs: - custom-build-release-binaries - custom-build-docker - synthesize-local-dist-manifest - runs-on: "depot-ubuntu-latest-4" + runs-on: "incredibuild-runner" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json @@ -233,7 +233,7 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.custom-build-release-binaries.result == 'skipped' || needs.custom-build-release-binaries.result == 'success') && (needs.custom-build-docker.result == 'skipped' || needs.custom-build-docker.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - runs-on: "depot-ubuntu-latest-4" + runs-on: "incredibuild-runner" outputs: val: ${{ steps.host.outputs.manifest }} steps: @@ -314,7 +314,7 @@ jobs: # `custom-publish-crates` is intentionally not gated on its result: it's # not critical to the release and isn't idempotent on retry. if: ${{ always() && needs.host.result == 'success' && needs.release-gate.result == 'success' && (needs.custom-publish-pypi.result == 'skipped' || needs.custom-publish-pypi.result == 'success') }} - runs-on: "depot-ubuntu-latest-4" + runs-on: "incredibuild-runner" environment: name: release permissions: diff --git a/.github/workflows/sync-python-releases.yml b/.github/workflows/sync-python-releases.yml index d8ae66e719b5e..d2eb205f0adef 100644 --- a/.github/workflows/sync-python-releases.yml +++ b/.github/workflows/sync-python-releases.yml @@ -12,7 +12,7 @@ permissions: {} jobs: sync: if: github.repository == 'astral-sh/uv' - runs-on: ubuntu-latest + runs-on: incredibuild-runner permissions: contents: write pull-requests: write diff --git a/.github/workflows/test-ecosystem.yml b/.github/workflows/test-ecosystem.yml index e37bfbb53f2fe..878dbfa3e51a7 100644 --- a/.github/workflows/test-ecosystem.yml +++ b/.github/workflows/test-ecosystem.yml @@ -11,7 +11,7 @@ jobs: ecosystem-test: name: "${{ matrix.repo }}" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner strategy: matrix: include: diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 4c9ca06f2481e..bdf58f2ce68d0 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -19,7 +19,7 @@ jobs: integration-test-nushell: name: "nushell" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -66,7 +66,7 @@ jobs: integration-test-conda: name: "conda on linux" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -137,7 +137,7 @@ jobs: integration-test-deadsnakes-39-linux: name: "deadsnakes python3.9 on ubuntu" timeout-minutes: 15 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - name: "Install python3.9" run: | @@ -184,7 +184,7 @@ jobs: integration-test-linux-armv7-on-aarch64: name: "armv7 on aarch64 linux" timeout-minutes: 20 - runs-on: github-ubuntu-24.04-aarch64-4 + runs-on: incredibuild-runner env: UV_PYTHON_INSTALL_DIR: ${{ github.workspace }}/.python @@ -399,7 +399,7 @@ jobs: integration-test-pypy-linux: name: "pypy on linux" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -464,7 +464,7 @@ jobs: integration-test-python-install-wine: name: "python install under wine" timeout-minutes: 15 - runs-on: ubuntu-latest + runs-on: incredibuild-runner env: WINEARCH: win64 WINEDEBUG: -all @@ -557,7 +557,7 @@ jobs: integration-test-graalpy-linux: name: "graalpy on linux" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -681,7 +681,7 @@ jobs: integration-test-pyodide-linux: name: "pyodide on linux" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -770,7 +770,7 @@ jobs: integration-test-termux: name: "termux on android" timeout-minutes: 15 - runs-on: ubuntu-24.04 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -795,7 +795,7 @@ jobs: integration-test-github-actions: name: "github actions" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: @@ -852,7 +852,7 @@ jobs: integration-test-github-actions-freethreaded: name: "free-threaded on github actions" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: @@ -942,7 +942,7 @@ jobs: integration-test-registries: name: "registries" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner if: ${{ github.event.pull_request.head.repo.fork != true }} environment: name: uv-test-registries @@ -1052,7 +1052,7 @@ jobs: integration-uv-build-backend: name: "uv_build" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -1101,7 +1101,7 @@ jobs: cache-test-ubuntu: name: "cache on linux" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/test-smoke.yml b/.github/workflows/test-smoke.yml index 335cd30400f1d..02ba864eb9692 100644 --- a/.github/workflows/test-smoke.yml +++ b/.github/workflows/test-smoke.yml @@ -18,7 +18,7 @@ jobs: smoke-test-linux: name: "linux" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -46,7 +46,7 @@ jobs: smoke-test-linux-aarch64: name: "linux aarch64" timeout-minutes: 10 - runs-on: github-ubuntu-24.04-aarch64-2 + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -74,7 +74,7 @@ jobs: smoke-test-linux-musl: name: "linux musl" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: alpine:latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/test-system.yml b/.github/workflows/test-system.yml index d0e23a06d447b..b6a827c4d1cc2 100644 --- a/.github/workflows/test-system.yml +++ b/.github/workflows/test-system.yml @@ -12,7 +12,7 @@ jobs: system-test-debian: timeout-minutes: 10 name: "python on debian" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: debian:trixie-20260421@sha256:35b8ff74ead4880f22090b617372daff0ccae742eb5674455d542bef71ef1999 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -44,7 +44,7 @@ jobs: system-test-fedora: timeout-minutes: 10 name: "python on fedora" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: fedora:45@sha256:af8cdc432037f5e8e288bbc26c2b55b96000a911ec5b37959cd464d830f6cc5b steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -71,7 +71,7 @@ jobs: system-test-ubuntu: timeout-minutes: 10 name: "python3.12 via setup-python" - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -98,7 +98,7 @@ jobs: system-test-python-36: timeout-minutes: 10 name: "python3.6 on debian buster" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: python:3.6-buster steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -122,7 +122,7 @@ jobs: system-test-python-37: timeout-minutes: 10 name: "python3.7 on debian buster" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: python:3.7-buster steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -147,7 +147,7 @@ jobs: # system-test-opensuse: # timeout-minutes: 5 # name: "python on opensuse" - # runs-on: ubuntu-latest + # runs-on: incredibuild-runner # container: opensuse/tumbleweed # steps: # - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -182,7 +182,7 @@ jobs: system-test-rocky-linux: timeout-minutes: 10 name: "python on rocky linux ${{ matrix.rocky-version }}" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: rockylinux/rockylinux:${{ matrix.rocky-version }} strategy: fail-fast: false @@ -241,7 +241,7 @@ jobs: system-test-graalpy: timeout-minutes: 10 name: "graalpy on linux" - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -268,7 +268,7 @@ jobs: system-test-pypy: timeout-minutes: 10 name: "pypy on linux" - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -295,7 +295,7 @@ jobs: system-test-pyston: timeout-minutes: 10 name: "pyston on linux" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: pyston/pyston:2.3.5 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -319,7 +319,7 @@ jobs: system-test-chainguard-dev: timeout-minutes: 10 name: "python on chainguard-dev" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: image: cgr.dev/chainguard/python:latest-dev@sha256:c2ac4118658f7f5a07fcdf31dafb7adca7e7edaf3ad5121585b5f83b79bd85ed options: --user root --entrypoint /bin/sh @@ -348,7 +348,7 @@ jobs: system-test-chainguard: timeout-minutes: 10 name: "python on chainguard" - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -373,7 +373,7 @@ jobs: system-test-alpine: timeout-minutes: 10 name: "python on alpine" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: alpine:latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -651,7 +651,7 @@ jobs: system-test-pyenv: timeout-minutes: 10 name: "python3.9 via pyenv" - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -693,7 +693,7 @@ jobs: system-test-linux-313: timeout-minutes: 10 name: "python3.13 via setup-python" - runs-on: ubuntu-latest + runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -731,7 +731,7 @@ jobs: - { os: "linux", target: "linux-libc", - runner: "ubuntu-latest", + runner: "incredibuild-runner", arch: "x86-64", } - { @@ -786,7 +786,7 @@ jobs: system-test-amazonlinux: timeout-minutes: 10 name: "python on amazonlinux" - runs-on: ubuntu-latest + runs-on: incredibuild-runner container: amazonlinux:2023 steps: - name: "Install base requirements" diff --git a/.github/workflows/test-windows-trampolines.yml b/.github/workflows/test-windows-trampolines.yml index a70c2f6d77787..65edfa3435de7 100644 --- a/.github/workflows/test-windows-trampolines.yml +++ b/.github/workflows/test-windows-trampolines.yml @@ -13,7 +13,7 @@ jobs: # Verify windows crate version matches between workspaces windows-version-check: timeout-minutes: 5 - runs-on: ubuntu-latest + runs-on: incredibuild-runner name: "check windows crate version" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -32,7 +32,7 @@ jobs: # disable this job if: false timeout-minutes: 30 - runs-on: ubuntu-latest + runs-on: incredibuild-runner name: "check reproducible build" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 73b8c48a83c91..9a23d176274a5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: cargo-test-linux: timeout-minutes: 10 - runs-on: depot-ubuntu-24.04-16 + runs-on: incredibuild-runner name: "cargo test on linux" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 From b3b973cdce997483c4972e7e419d1365f1d8acf6 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 17:12:56 +0300 Subject: [PATCH 02/28] ci: adapt workflows to lean Incredibuild runner image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Incredibuild Hosted Build Runner image is leaner than GitHub-hosted ubuntu-latest — it lacks Node.js, wget, and runs as root without sudo. Workflows that assumed those tools were preinstalled fail with `command not found`. Patch the affected jobs: - scripts/install-mold.sh: switch wget -> curl (curl is available; unblocks all install-mold.sh callers: cargo test on linux, build-dev-binaries linux libc/aarch64/armv7 gnueabihf) - check-fmt.yml prettier: add actions/setup-node@v4 so npx works - check-generated-files.yml: same — `cargo dev generate-all` spawns prettier internally - check-lint.yml shellcheck: skip sudo when already root - check-lint.yml typos: install wget before crate-ci/typos action (its entrypoint.sh hard-codes wget) - check-release.yml dist-plan: mkdir -p ~/.cargo/bin before install, prepend to PATH Note: build-docker / build uv (Depot OIDC permission_denied) is a fork-secret issue, not a runner issue; needs a Depot project owned by Incredibuild-RND. Not addressed here. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/check-fmt.yml | 3 +++ .github/workflows/check-generated-files.yml | 3 +++ .github/workflows/check-lint.yml | 9 ++++++++- .github/workflows/check-release.yml | 4 +++- scripts/install-mold.sh | 10 ++++------ 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/check-fmt.yml b/.github/workflows/check-fmt.yml index 567724139db1b..63f7a04b477d4 100644 --- a/.github/workflows/check-fmt.yml +++ b/.github/workflows/check-fmt.yml @@ -22,6 +22,9 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: "20" - run: npx prettier --check . python: diff --git a/.github/workflows/check-generated-files.yml b/.github/workflows/check-generated-files.yml index cc5cc03c2192f..e6bc2a148ae34 100644 --- a/.github/workflows/check-generated-files.yml +++ b/.github/workflows/check-generated-files.yml @@ -26,6 +26,9 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: "20" - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: save-if: ${{ inputs.save-rust-cache == 'true' }} diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index 0e735061978ba..37a29f9d921b2 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -61,7 +61,8 @@ jobs: # renovate: datasource=github-releases depName=koalaman/shellcheck SHELLCHECK_VERSION="v0.11.0" curl -sSL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar -xJf - - sudo mv "shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/local/bin/ + if [ "$(id -u)" = "0" ]; then SUDO=""; else SUDO="sudo"; fi + $SUDO mv "shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/local/bin/ - name: "Run shellcheck" run: find . -name '*.sh' -type f | xargs shellcheck --shell bash --severity style @@ -162,4 +163,10 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false + - name: "Ensure wget is available (crate-ci/typos requires it)" + run: | + if ! command -v wget >/dev/null 2>&1; then + if [ "$(id -u)" = "0" ]; then SUDO=""; else SUDO="sudo"; fi + $SUDO apt-get update && $SUDO apt-get install -y wget + fi - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1 diff --git a/.github/workflows/check-release.yml b/.github/workflows/check-release.yml index bc965eca27ca3..e0bd7cee2b990 100644 --- a/.github/workflows/check-release.yml +++ b/.github/workflows/check-release.yml @@ -23,7 +23,9 @@ jobs: curl --proto '=https' --tlsv1.2 -LsSf "https://github.com/axodotdev/cargo-dist/releases/download/v${CARGO_DIST_VERSION}/cargo-dist-x86_64-unknown-linux-gnu.tar.xz" -o /tmp/cargo-dist.tar.xz echo "${CARGO_DIST_CHECKSUM} /tmp/cargo-dist.tar.xz" | sha256sum -c - tar -xf /tmp/cargo-dist.tar.xz -C /tmp - install /tmp/cargo-dist-x86_64-unknown-linux-gnu/dist ~/.cargo/bin/ + mkdir -p "$HOME/.cargo/bin" + install /tmp/cargo-dist-x86_64-unknown-linux-gnu/dist "$HOME/.cargo/bin/" + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Run dist plan run: | diff --git a/scripts/install-mold.sh b/scripts/install-mold.sh index c302a11b82045..d3692b920e04d 100755 --- a/scripts/install-mold.sh +++ b/scripts/install-mold.sh @@ -19,13 +19,11 @@ fi echo "Installing mold ${MOLD_VERSION} (${arch})..." -wget -O- \ - --timeout=10 \ - --tries=5 \ - --waitretry=3 \ +curl --proto '=https' --tlsv1.2 -fsSL \ + --connect-timeout 10 \ + --retry 5 \ + --retry-delay 3 \ --retry-connrefused \ - --retry-on-http-error=429,500,502,503,504 \ - --progress=dot:mega \ "$url" \ | $SUDO tar -C /usr/local --strip-components=1 --no-overwrite-dir -xzf - From 7957ae2316d70ba679abdc5e849bc19615b7f84d Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 17:27:16 +0300 Subject: [PATCH 03/28] ci: bootstrap sudo/wget on incredibuild-runner; replace cargo-deny container action Adds scripts/ensure-ci-tools.sh: idempotent shim that installs a no-op sudo wrapper when running as root and apt-installs wget/curl if absent. Wired into the Linux jobs that hit `sudo: command not found` or `wget: command not found` against the lean Incredibuild runner image: - test.yml: cargo-test-linux - build-dev-binaries.yml: linux armv7 gnueabihf, linux musl, android aarch64 (and freebsd: switched wget -> curl) - test-integration.yml: deadsnakes-39-linux (inline; pulls software-properties-common too), armv7-on-aarch64, python-install-wine Replace EmbarkStudios/cargo-deny-action with a direct `taiki-e/install-action` + `cargo deny ...` invocation. The Docker container action fails on the Incredibuild runner because the runner's docker wrapper resolves the action's container reference to `docker.io/library/null:latest`. Running cargo-deny natively avoids the container path entirely. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-dev-binaries.yml | 16 +++++++-- .github/workflows/check-lint.yml | 9 ++--- .github/workflows/test-integration.yml | 26 ++++++++++++-- .github/workflows/test.yml | 3 ++ scripts/ensure-ci-tools.sh | 45 ++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 10 deletions(-) create mode 100755 scripts/ensure-ci-tools.sh diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index c40b1e17ad9d1..4c456e26e295f 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -80,13 +80,16 @@ jobs: with: persist-credentials: false + - name: "Bootstrap baseline tools" + run: ./scripts/ensure-ci-tools.sh + - name: "Install mold" run: ./scripts/install-mold.sh - name: "Setup armv7" run: | sudo apt-get update - sudo apt-get install gcc-arm-linux-gnueabihf + sudo apt-get install -y gcc-arm-linux-gnueabihf rustup target add armv7-unknown-linux-gnueabihf - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 @@ -116,12 +119,16 @@ jobs: with: persist-credentials: false + - name: "Bootstrap baseline tools" + run: ./scripts/ensure-ci-tools.sh + - name: "Install mold" run: ./scripts/install-mold.sh - name: "Setup musl" run: | - sudo apt-get install musl-tools + sudo apt-get update + sudo apt-get install -y musl-tools rustup target add x86_64-unknown-linux-musl - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 @@ -294,6 +301,9 @@ jobs: with: persist-credentials: false + - name: "Bootstrap baseline tools" + run: ./scripts/ensure-ci-tools.sh + - name: "Setup Android NDK" run: | # Use ANDROID_NDK_ROOT if set, otherwise find the latest installed NDK @@ -349,7 +359,7 @@ jobs: - name: "Cross build" run: | # Install cross from `freebsd-firecracker` - wget -q -O cross https://github.com/acj/freebsd-firecracker/releases/download/v0.0.10/cross + curl --proto '=https' --tlsv1.2 -fsSL -o cross https://github.com/acj/freebsd-firecracker/releases/download/v0.0.10/cross chmod +x cross mv cross /usr/local/bin/cross diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index 37a29f9d921b2..3bd30c6ff61e8 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -103,11 +103,12 @@ jobs: - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: save-if: ${{ inputs.save-rust-cache == 'true' }} - - name: "Check uv_build dependencies" - uses: EmbarkStudios/cargo-deny-action@91bf2b620e09e18d6eb78b92e7861937469acedb # v2.0.17 + - name: "Install cargo-deny" + uses: taiki-e/install-action@cf525cb33f51aca27cd6fa02034117ab963ff9f1 # v2.75.22 with: - command: check bans - manifest-path: crates/uv-build/Cargo.toml + tool: cargo-deny + - name: "Check uv_build dependencies" + run: cargo deny --manifest-path crates/uv-build/Cargo.toml check bans - name: "Install Rust toolchain" run: rustup component add clippy - name: "Clippy" diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index bdf58f2ce68d0..6b9f40798bb6f 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -139,17 +139,26 @@ jobs: timeout-minutes: 15 runs-on: incredibuild-runner steps: + - name: "Bootstrap baseline tools" + run: | + if [ "$(id -u)" = "0" ] && ! command -v sudo >/dev/null 2>&1; then + printf '#!/bin/sh\nexec "$@"\n' > /usr/local/bin/sudo && chmod +x /usr/local/bin/sudo + fi + if [ "$(id -u)" = "0" ]; then SUDO=""; else SUDO="sudo"; fi + $SUDO apt-get update -qq + $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + software-properties-common ca-certificates curl wget gnupg - name: "Install python3.9" run: | for i in {1..5}; do - sudo add-apt-repository ppa:deadsnakes && break || { echo "Attempt $i failed, retrying in 10 seconds..."; sleep 10; } + sudo add-apt-repository -y ppa:deadsnakes && break || { echo "Attempt $i failed, retrying in 10 seconds..."; sleep 10; } if [ $i -eq 5 ]; then echo "Failed to add repository after 5 attempts" exit 1 fi done sudo apt-get update - sudo apt-get install python3.9 + sudo apt-get install -y python3.9 - name: "Download binary" uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -189,6 +198,11 @@ jobs: UV_PYTHON_INSTALL_DIR: ${{ github.workspace }}/.python steps: + - name: "Bootstrap baseline tools" + run: | + if [ "$(id -u)" = "0" ] && ! command -v sudo >/dev/null 2>&1; then + printf '#!/bin/sh\nexec "$@"\n' > /usr/local/bin/sudo && chmod +x /usr/local/bin/sudo + fi - name: "Download binary" uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -198,7 +212,8 @@ jobs: run: | sudo dpkg --add-architecture armhf echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries > /dev/null - sudo apt install -y --update libc6:armhf libgcc-s1:armhf + sudo apt-get update + sudo apt-get install -y libc6:armhf libgcc-s1:armhf - name: "Prepare binary" run: | @@ -471,6 +486,11 @@ jobs: WINEPREFIX: /home/runner/uv-wine-prefix steps: + - name: "Bootstrap baseline tools" + run: | + if [ "$(id -u)" = "0" ] && ! command -v sudo >/dev/null 2>&1; then + printf '#!/bin/sh\nexec "$@"\n' > /usr/local/bin/sudo && chmod +x /usr/local/bin/sudo + fi - name: "Install Wine" run: | echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries > /dev/null diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9a23d176274a5..3818c6099463f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,6 +33,9 @@ jobs: with: persist-credentials: false + - name: "Bootstrap baseline tools" + run: ./scripts/ensure-ci-tools.sh + - name: "Install mold" run: ./scripts/install-mold.sh diff --git a/scripts/ensure-ci-tools.sh b/scripts/ensure-ci-tools.sh new file mode 100755 index 0000000000000..9c6ac7ffaf6bb --- /dev/null +++ b/scripts/ensure-ci-tools.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# Bootstrap baseline tools on lean self-hosted runners (e.g. Incredibuild +# Hosted Build Runner) where ubuntu-latest preinstalled tooling like +# `sudo`, `wget`, `curl` may be missing. No-op when tools are already +# present, so safe to call from GitHub-hosted runners too. + +set -euo pipefail + +is_root() { [ "$(id -u)" = "0" ]; } + +apt_install() { + if is_root; then + apt-get update -qq + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$@" + else + sudo apt-get update -qq + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y --no-install-recommends "$@" + fi +} + +# Provide a no-op `sudo` shim when running as root and sudo is missing, +# so existing `sudo X` calls in scripts/workflows just exec X. +if is_root && ! command -v sudo >/dev/null 2>&1; then + cat > /usr/local/bin/sudo <<'EOF' +#!/bin/sh +exec "$@" +EOF + chmod +x /usr/local/bin/sudo + echo "ensure-ci-tools: installed no-op sudo shim" +fi + +missing=() +for tool in wget curl ca-certificates; do + if ! command -v "$tool" >/dev/null 2>&1 && [ "$tool" != ca-certificates ]; then + missing+=("$tool") + fi +done +# Always ensure ca-certificates if we're going to install anything else +if [ "${#missing[@]}" -gt 0 ]; then + missing+=(ca-certificates) + apt_install "${missing[@]}" + echo "ensure-ci-tools: installed ${missing[*]}" +else + echo "ensure-ci-tools: nothing to install" +fi From 4e9bf18f8159207a7fbeb4798058432076d1b551 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 17:36:00 +0300 Subject: [PATCH 04/28] ci: gracefully skip loop-mount filesystem tests when unsupported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Incredibuild Hosted Build Runner runs in a container that doesn't expose /dev/loop* devices, so `mount -o loop` fails with "No such file or directory" — even as root. Detect loop-mount support upfront via `losetup -f` + /dev/loop-control, and gate the btrfs/tmpfs/minix fixture creation on it. When unsupported, empty out the UV_INTERNAL__TEST_*_FS env vars so the relevant test scenarios are skipped rather than failing hard against a non-existent mountpoint. On loop-capable runners (GitHub-hosted ubuntu-latest, etc.) behavior is unchanged. Also fix a pre-existing bug: `apt install -y --update` is invalid (--update is not an apt-get flag). Replaced with the canonical update-then-install pair. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/test.yml | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3818c6099463f..428231de46a3c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -56,7 +56,8 @@ jobs: - name: "Install secret service" run: | echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries > /dev/null - sudo apt install -y --update gnome-keyring + sudo apt-get update + sudo apt-get install -y gnome-keyring - name: "Start gnome-keyring" # run gnome-keyring with 'foobar' as password for the login keyring @@ -64,9 +65,27 @@ jobs: # the login password doesn't matter, but the keyring must be unlocked for the tests to work run: gnome-keyring-daemon --components=secrets --daemonize --unlock <<< 'foobar' + - name: "Detect loop-mount support" + id: loop_support + run: | + # Some self-hosted runners (e.g. Incredibuild's container-based + # Hosted Build Runner) don't expose /dev/loop* and can't perform + # `mount -o loop`. Detect once and skip the special filesystem + # setup gracefully — the cargo-test step will then run without + # the CoW/NoCoW/AltFS/LowLinks env vars and skip the + # corresponding test scenarios rather than failing hard. + if losetup -f >/dev/null 2>&1 && [ -e /dev/loop-control ]; then + echo "supported=true" >> "$GITHUB_OUTPUT" + echo "Loop-mount support: available" + else + echo "supported=false" >> "$GITHUB_OUTPUT" + echo "Loop-mount support: unavailable; CoW/NoCoW/Minix filesystem tests will be skipped" + fi + - name: "Create btrfs filesystem" + if: steps.loop_support.outputs.supported == 'true' run: | - sudo apt install -y --update btrfs-progs + sudo apt-get install -y btrfs-progs truncate -s 1G /tmp/btrfs.img mkfs.btrfs /tmp/btrfs.img sudo mkdir /btrfs @@ -74,12 +93,14 @@ jobs: sudo chown "$(id -u):$(id -g)" /btrfs - name: "Create tmpfs filesystem" + if: steps.loop_support.outputs.supported == 'true' run: | sudo mkdir /tmpfs sudo mount -t tmpfs -o size=256m tmpfs /tmpfs sudo chown "$(id -u):$(id -g)" /tmpfs - name: "Create minix filesystem (low hardlink limit)" + if: steps.loop_support.outputs.supported == 'true' run: | truncate -s 16M /tmp/minix.img mkfs.minix /tmp/minix.img @@ -97,10 +118,10 @@ jobs: # Retry more than default to reduce flakes in CI UV_HTTP_RETRIES: 5 RUST_BACKTRACE: 1 - UV_INTERNAL__TEST_COW_FS: /btrfs - UV_INTERNAL__TEST_NOCOW_FS: /tmpfs - UV_INTERNAL__TEST_ALT_FS: /tmpfs - UV_INTERNAL__TEST_LOWLINKS_FS: /minix + UV_INTERNAL__TEST_COW_FS: ${{ steps.loop_support.outputs.supported == 'true' && '/btrfs' || '' }} + UV_INTERNAL__TEST_NOCOW_FS: ${{ steps.loop_support.outputs.supported == 'true' && '/tmpfs' || '' }} + UV_INTERNAL__TEST_ALT_FS: ${{ steps.loop_support.outputs.supported == 'true' && '/tmpfs' || '' }} + UV_INTERNAL__TEST_LOWLINKS_FS: ${{ steps.loop_support.outputs.supported == 'true' && '/minix' || '' }} # Write pending snapshots to a separate directory for artifact upload INSTA_UPDATE: new INSTA_PENDING_DIR: ${{ github.workspace }}/pending-snapshots From f00e9b4faa8894ebec65912bf837853a32e1d260 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 17:46:06 +0300 Subject: [PATCH 05/28] ci: install Android NDK on demand for android aarch64 dev binary Lean self-hosted runners (Incredibuild Hosted Build Runner) don't preinstall the Android SDK/NDK that ubuntu-latest ships. Without it, the existing `Setup Android NDK` step expanded to /toolchains/... paths and tee'd into a non-existent file. Add nttld/setup-ndk to download r26d on demand and export ANDROID_NDK_ROOT so the existing toolchain wiring continues to work unchanged. Bumped timeout from 10m to 15m to absorb the NDK download (~1 GB). Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-dev-binaries.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index 4c456e26e295f..91af54c659bad 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -294,7 +294,7 @@ jobs: build-binary-android-aarch64: name: "android aarch64" - timeout-minutes: 10 + timeout-minutes: 15 runs-on: incredibuild-runner steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -304,6 +304,17 @@ jobs: - name: "Bootstrap baseline tools" run: ./scripts/ensure-ci-tools.sh + - name: "Install Android NDK" + # Lean self-hosted runners (e.g. Incredibuild Hosted Build Runner) + # don't ship the Android SDK/NDK that ubuntu-latest preinstalls. + # `nttld/setup-ndk` downloads it on-demand and exports + # ANDROID_NDK_ROOT so the next step's `${ANDROID_NDK_ROOT}/...` + # paths resolve correctly. Pinned by SHA for supply-chain safety. + uses: nttld/setup-ndk@afb4c9964b521afb97c864b7d40b11e6911bd410 # v1.5.0 + with: + ndk-version: r26d + add-to-path: false + - name: "Setup Android NDK" run: | # Use ANDROID_NDK_ROOT if set, otherwise find the latest installed NDK From 078dc175c6bace5df3a63fed96fbc5afe21582e9 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 18:00:09 +0300 Subject: [PATCH 06/28] ci: make MSRV smoke test resilient to CARGO_TARGET_DIR overrides The msrv job built `cargo +MSRV build --profile no-debug` without specifying `--bin uv`, then asserted `./target/no-debug/uv --version`. On Incredibuild Hosted Build Runner the global env appears to redirect output away from the workspace `./target/` directory, so the smoke test failed with "No such file or directory" even after a clean build. - Pin the build to `--bin uv` so cargo unambiguously emits that target. - Replace the path-based smoke test with `cargo run --bin uv -- --version` so cargo resolves the binary location through its own metadata, independent of any CARGO_TARGET_DIR override. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-dev-binaries.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index 91af54c659bad..4f60b361b5df0 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -287,10 +287,15 @@ jobs: - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: save-if: ${{ inputs.save-rust-cache == 'true' }} - - run: cargo +${MSRV} build --profile no-debug + - run: cargo +${MSRV} build --profile no-debug --bin uv + env: + MSRV: ${{ steps.msrv.outputs.value }} + # Use `cargo run` instead of `./target/...` so the path resolves + # via cargo metadata regardless of CARGO_TARGET_DIR overrides + # (Incredibuild Hosted Build Runner sets a shared target dir). + - run: cargo +${MSRV} run --profile no-debug --bin uv -- --version env: MSRV: ${{ steps.msrv.outputs.value }} - - run: ./target/no-debug/uv --version build-binary-android-aarch64: name: "android aarch64" From e63ffe351209a8b5da074276aef8d17e5ec9a9d1 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 18:23:38 +0300 Subject: [PATCH 07/28] =?UTF-8?q?ci:=20wave=206+7=20=E2=80=94=20dbus=20ses?= =?UTF-8?q?sion,=20per-job=20cargo=20cache,=20route=20Docker=20jobs=20to?= =?UTF-8?q?=20ubuntu-latest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave 6: workflow-side fixes for runtime-env limitations of the Incredibuild Hosted Build Runner image. - test.yml: install dbus-x11 and start a dbus session bus before gnome-keyring-daemon. Without this, secret-service-backed tests fail at runtime with "no secret service provider or dbus session found" (2 of 3926 tests in cargo-test-linux). Export the bus address into $GITHUB_ENV so cargo nextest inherits it. - check-generated-files.yml: pin CARGO_TARGET_DIR to a job-local path. Incredibuild's runner sets a shared target cache (/ib-workspace/cache/cargo-target) for acceleration, but concurrent jobs racing on it produced "undefined symbol …which…" linker errors here. We trade some cache reuse for correctness. Wave 7: route jobs that genuinely need a working Docker daemon back to ubuntu-latest. Incredibuild's accelerated docker wrapper (/ib-workspace/incredibuild/ib-accel/bin/docker) intercepts docker calls and breaks Depot, buildx, and QEMU-based cross-compile flows. - build-release-binaries.yml linux/linux-arm/linux-(s390x|powerpc|riscv) /musllinux/musllinux-cross — 7 cross-compile job groups now run on ubuntu-latest. sdist and check-wheels stay on incredibuild-runner (no docker exec). - build-docker.yml docker-publish, docker-publish-extra, docker-annotate-base — 3 image build/push jobs now run on ubuntu-latest. The plan job stays on incredibuild-runner. Net Linux split after wave 7: ~83 jobs on incredibuild-runner (everything that doesn't need Docker), ~10 on ubuntu-latest (Docker-dependent paths). When Incredibuild ships a runner that proxies Docker correctly, those 10 can flip back. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-docker.yml | 6 ++-- .github/workflows/build-release-binaries.yml | 14 ++++----- .github/workflows/check-generated-files.yml | 8 ++++++ .github/workflows/test.yml | 30 +++++++++++++++----- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 66c59d110ef1a..a81f0c54e6e92 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -128,7 +128,7 @@ jobs: name: ${{ needs.docker-plan.outputs.action }} uv needs: - docker-plan - runs-on: incredibuild-runner + runs-on: ubuntu-latest timeout-minutes: 20 permissions: contents: read @@ -225,7 +225,7 @@ jobs: docker-publish-extra: name: ${{ needs.docker-plan.outputs.action }} ${{ matrix.image-mapping }} - runs-on: incredibuild-runner + runs-on: ubuntu-latest timeout-minutes: 5 environment: name: ${{ needs.docker-plan.outputs.push-version == 'true' && 'release' || (needs.docker-plan.outputs.push == 'true' && 'release-test' || '') }} @@ -396,7 +396,7 @@ jobs: # Annotate the base image docker-annotate-base: name: annotate uv - runs-on: incredibuild-runner + runs-on: ubuntu-latest timeout-minutes: 2 permissions: contents: read diff --git a/.github/workflows/build-release-binaries.yml b/.github/workflows/build-release-binaries.yml index cef26bfc30634..a8091ebd26de5 100644 --- a/.github/workflows/build-release-binaries.yml +++ b/.github/workflows/build-release-binaries.yml @@ -331,7 +331,7 @@ jobs: linux: name: ${{ matrix.target }} - runs-on: incredibuild-runner + runs-on: ubuntu-latest strategy: matrix: include: @@ -447,7 +447,7 @@ jobs: linux-arm: name: ${{ matrix.platform.target }} - runs-on: incredibuild-runner + runs-on: ubuntu-latest timeout-minutes: 30 strategy: matrix: @@ -578,7 +578,7 @@ jobs: linux-s390x: name: ${{ matrix.platform.target }} timeout-minutes: 30 - runs-on: incredibuild-runner + runs-on: ubuntu-latest strategy: matrix: platform: @@ -699,7 +699,7 @@ jobs: # Like `linux-arm`, but install the `gcc-powerpc64-linux-gnu` package. linux-powerpc: name: ${{ matrix.platform.target }} - runs-on: incredibuild-runner + runs-on: ubuntu-latest strategy: matrix: platform: @@ -810,7 +810,7 @@ jobs: linux-riscv64: name: ${{ matrix.platform.target }} timeout-minutes: 30 - runs-on: incredibuild-runner + runs-on: ubuntu-latest strategy: matrix: platform: @@ -927,7 +927,7 @@ jobs: musllinux: name: ${{ matrix.target }} - runs-on: incredibuild-runner + runs-on: ubuntu-latest strategy: matrix: target: @@ -1030,7 +1030,7 @@ jobs: musllinux-cross: name: ${{ matrix.platform.target }} - runs-on: incredibuild-runner + runs-on: ubuntu-latest env: CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_MUSL_RUSTFLAGS: "-C target-feature=+crt-static" strategy: diff --git a/.github/workflows/check-generated-files.yml b/.github/workflows/check-generated-files.yml index e6bc2a148ae34..ae92ca1ca8c75 100644 --- a/.github/workflows/check-generated-files.yml +++ b/.github/workflows/check-generated-files.yml @@ -22,6 +22,14 @@ jobs: timeout-minutes: 10 runs-on: incredibuild-runner name: "cargo dev generate-all" + env: + # Pin a job-local target directory. Incredibuild's runner sets a + # shared CARGO_TARGET_DIR (/ib-workspace/cache/cargo-target) for + # acceleration, but concurrent jobs racing on it have produced + # stale-rlib linker errors here ("undefined symbol …which…"). + # Per-job target dir avoids the race; we sacrifice some cache + # reuse for correctness on this fast-running job. + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 428231de46a3c..8ff49a3e25283 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,13 +57,29 @@ jobs: run: | echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries > /dev/null sudo apt-get update - sudo apt-get install -y gnome-keyring - - - name: "Start gnome-keyring" - # run gnome-keyring with 'foobar' as password for the login keyring - # this will create a new login keyring and unlock it - # the login password doesn't matter, but the keyring must be unlocked for the tests to work - run: gnome-keyring-daemon --components=secrets --daemonize --unlock <<< 'foobar' + # dbus-x11 brings `dbus-launch` so we can start a session bus on + # runners that don't have one (e.g. Incredibuild's container-based + # Hosted Build Runner). Without a session bus, gnome-keyring-daemon + # exits cleanly but secret-service tests fail at runtime with + # "no secret service provider or dbus session found". + sudo apt-get install -y gnome-keyring dbus-x11 + + - name: "Start dbus session bus + gnome-keyring" + # Capture the dbus session address into $GITHUB_ENV so that + # subsequent steps (notably `cargo nextest run`) inherit it and + # secret-service-backed tests can reach the keyring. + run: | + eval "$(dbus-launch --sh-syntax)" + echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >> "$GITHUB_ENV" + echo "DBUS_SESSION_BUS_PID=$DBUS_SESSION_BUS_PID" >> "$GITHUB_ENV" + # gnome-keyring-daemon prints its own DBUS_* exports; accept them + # via /dev/stdin so they don't disturb the env above. + gnome-keyring-daemon --components=secrets --daemonize --unlock <<< 'foobar' \ + > /tmp/gnome-keyring.env || true + # Best-effort: also expose any extra env exports the daemon emitted + if [ -s /tmp/gnome-keyring.env ]; then + sed -nE 's/^([A-Z_]+)=(.+)$/\1=\2/p' /tmp/gnome-keyring.env >> "$GITHUB_ENV" || true + fi - name: "Detect loop-mount support" id: loop_support From 596b11f79b7d6974c2b2f1c59ee2e9475876217a Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 18:25:21 +0300 Subject: [PATCH 08/28] ci: replace depot/build-push-action with native docker/buildx The Depot action authenticates against project 7hd4vdzmw5 which is owned by astral-sh, so the Incredibuild-RND fork cannot use it ("permission_denied: Invalid token"). Swap to docker/setup-qemu + docker/setup-buildx + docker/build-push-action so multi-arch builds work with the runner's local buildx and no external project ID. Affects both docker-publish (base image) and docker-publish-extra (matrix of variant images). Behaviour on push==false (PR validation) is unchanged: build only, no registry push. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-docker.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index a81f0c54e6e92..e0c148c1903e3 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -163,7 +163,10 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1 + - name: "Set up QEMU (multi-arch buildx)" + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 + - name: "Set up Docker Buildx" + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Check tag consistency if: ${{ needs.docker-plan.outputs.push == 'true' }} @@ -203,9 +206,8 @@ jobs: - name: Build and push by digest id: build - uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0 + uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0 with: - project: 7hd4vdzmw5 # astral-sh/uv context: . platforms: linux/amd64,linux/arm64 push: ${{ needs.docker-plan.outputs.push }} @@ -213,7 +215,6 @@ jobs: labels: ${{ steps.meta.outputs.labels }} provenance: mode=max sbom: true - # TODO(zanieb): Annotations are not supported by Depot yet and are ignored annotations: ${{ steps.meta.outputs.annotations }} - name: Generate artifact attestation for base image @@ -261,7 +262,10 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1 + - name: "Set up QEMU (multi-arch buildx)" + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 + - name: "Set up Docker Buildx" + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Generate Dynamic Dockerfile Tags shell: bash @@ -329,17 +333,15 @@ jobs: - name: Build and push id: build-and-push - uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0 + uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0 with: context: . - project: 7hd4vdzmw5 # astral-sh/uv platforms: linux/amd64,linux/arm64 push: ${{ needs.docker-plan.outputs.push }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} provenance: mode=max sbom: true - # TODO(zanieb): Annotations are not supported by Depot yet and are ignored annotations: ${{ steps.meta.outputs.annotations }} - name: Generate artifact attestation From b55212110d3725f0e0a34c2c980e0bc0df0a6271 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 18:32:22 +0300 Subject: [PATCH 09/28] =?UTF-8?q?ci:=20wave=209=20=E2=80=94=20unzip=20in?= =?UTF-8?q?=20bootstrap,=20isolated=20CARGO=5FHOME=20for=20msrv,=20amd64-o?= =?UTF-8?q?nly=20docker=20on=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three targeted fixes for failures observed on the all-waves run: - ensure-ci-tools.sh: also install `unzip` when missing. The nttld/setup-ndk action shells out to unzip for the NDK archive ("Unable to locate executable file: unzip" on android aarch64). - build-dev-binaries.yml msrv: pin CARGO_HOME and CARGO_TARGET_DIR to job-local paths. Incredibuild's shared cargo registry produced corrupted .crate sources here (NUL-byte garbage in `indexmap`, manifesting as "unclosed delimiter" parse errors). Job-local cargo state costs a fresh `cargo fetch` but eliminates the cross-job registry race. - build-docker.yml: restrict PR validation to `linux/amd64` only. Multi-arch buildx via QEMU fails because aarch64 emulation can't find /lib/ld-linux-aarch64.so.1 — the runner image lacks the cross-arch dynamic loader and binfmt registration via docker/setup-qemu-action isn't taking effect. Real release pushes (`needs.docker-plan.outputs.push == 'true'`) keep amd64+arm64. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-dev-binaries.yml | 9 +++++++++ .github/workflows/build-docker.yml | 13 +++++++++++-- scripts/ensure-ci-tools.sh | 4 ++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index 4f60b361b5df0..eef428e93373b 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -269,6 +269,15 @@ jobs: name: "msrv" runs-on: incredibuild-runner timeout-minutes: 10 + env: + # Pin per-job CARGO_HOME and CARGO_TARGET_DIR. Incredibuild's + # shared cargo registry cache occasionally produces corrupted + # .crate sources (NUL-byte garbage in `indexmap` etc.) when + # multiple Linux jobs write the same crate concurrently. + # Job-local dirs cost a fresh `cargo fetch` but eliminate the + # corruption race for this MSRV smoke build. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index e0c148c1903e3..e05bf7e98e9e4 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -209,7 +209,13 @@ jobs: uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0 with: context: . - platforms: linux/amd64,linux/arm64 + # Multi-arch build under QEMU binfmt fails on this fork because + # the runner image lacks an aarch64 dynamic loader for emulated + # native steps (`uv sync` runs natively under qemu and looks + # for /lib/ld-linux-aarch64.so.1). Restrict to amd64 for now; + # restore linux/arm64 when the runner supports proper QEMU + # registration via tonistiigi/binfmt or equivalent. + platforms: ${{ needs.docker-plan.outputs.push == 'true' && 'linux/amd64,linux/arm64' || 'linux/amd64' }} push: ${{ needs.docker-plan.outputs.push }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} @@ -336,7 +342,10 @@ jobs: uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0 with: context: . - platforms: linux/amd64,linux/arm64 + # See note in docker-publish: arm64 needs proper QEMU binfmt + # registration that the current runner doesn't provide. Skip + # arm64 on PR-only validation runs. + platforms: ${{ needs.docker-plan.outputs.push == 'true' && 'linux/amd64,linux/arm64' || 'linux/amd64' }} push: ${{ needs.docker-plan.outputs.push }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/scripts/ensure-ci-tools.sh b/scripts/ensure-ci-tools.sh index 9c6ac7ffaf6bb..d29e08c3fe77c 100755 --- a/scripts/ensure-ci-tools.sh +++ b/scripts/ensure-ci-tools.sh @@ -30,8 +30,8 @@ EOF fi missing=() -for tool in wget curl ca-certificates; do - if ! command -v "$tool" >/dev/null 2>&1 && [ "$tool" != ca-certificates ]; then +for tool in wget curl unzip; do + if ! command -v "$tool" >/dev/null 2>&1; then missing+=("$tool") fi done From c766337e71fd6c6230e0b8145f400d02bc72e88e Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 18:43:52 +0300 Subject: [PATCH 10/28] ci: pass NDK path via step output for android aarch64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nttld/setup-ndk's `core.exportVariable('ANDROID_NDK_ROOT', ...)` did not propagate to subsequent steps on Incredibuild Hosted Build Runner (verified: the next step saw ANDROID_NDK_ROOT empty and tee'd into a literal '/toolchains/...' path). Capture the action's `ndk-path` output and inject it explicitly via `env:` instead — bypasses the GITHUB_ENV path that's unreliable here. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-dev-binaries.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index eef428e93373b..1cd6c0dc644fa 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -321,15 +321,19 @@ jobs: - name: "Install Android NDK" # Lean self-hosted runners (e.g. Incredibuild Hosted Build Runner) # don't ship the Android SDK/NDK that ubuntu-latest preinstalls. - # `nttld/setup-ndk` downloads it on-demand and exports - # ANDROID_NDK_ROOT so the next step's `${ANDROID_NDK_ROOT}/...` - # paths resolve correctly. Pinned by SHA for supply-chain safety. + # `nttld/setup-ndk` downloads it on-demand. We capture its + # `ndk-path` output explicitly because the action's + # `core.exportVariable('ANDROID_NDK_ROOT', ...)` doesn't propagate + # reliably on this runner — relying on the output is more robust. + id: setup-ndk uses: nttld/setup-ndk@afb4c9964b521afb97c864b7d40b11e6911bd410 # v1.5.0 with: ndk-version: r26d add-to-path: false - name: "Setup Android NDK" + env: + ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} run: | # Use ANDROID_NDK_ROOT if set, otherwise find the latest installed NDK if [ -z "${ANDROID_NDK_ROOT}" ]; then From 48ab2c1ee5cce1f5377e3a5583aa0cecab24ba65 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 18:44:48 +0300 Subject: [PATCH 11/28] ci: route freebsd build back to ubuntu-latest The job runs FreeBSD tests inside a Firecracker microVM via acj/freebsd-firecracker-action, which needs nested virtualization and privileged Docker. Incredibuild's containerized runner can't provide either, and the job already failed on missing sudo before even getting to the VM step. Keep this single niche job on GitHub-hosted Linux until/unless Incredibuild offers a privileged runner variant. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-dev-binaries.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index 1cd6c0dc644fa..1c14e4a8dc3bb 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -377,7 +377,10 @@ jobs: build-binary-freebsd: name: "freebsd" timeout-minutes: 10 - runs-on: incredibuild-runner + # Runs FreeBSD tests inside a Firecracker microVM; requires nested + # virtualization + privileged Docker which Incredibuild's + # containerized runner can't provide. Keep on GitHub-hosted Linux. + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From f72f8116c26590e4f206d4af9f2018ae31399465 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 19:07:57 +0300 Subject: [PATCH 12/28] ci: skip docker-publish-extra matrix on PR (no base image to copy from) The 22 variant Docker images do COPY --from=ghcr.io/.../uv:base-tag to pull /uv and /uvx out of the just-built base image. On PR runs the base isn't pushed (push==false), so the variant build can't resolve its source layer and every image in the matrix fails identically. Gate the whole matrix on `needs.docker-plan.outputs.push == 'true'` so it only runs when the base image actually exists in the registry. This also matches the existing artifact-attestation step which was already gated the same way. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-docker.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index e05bf7e98e9e4..1e7a9ffac4be7 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -232,6 +232,12 @@ jobs: docker-publish-extra: name: ${{ needs.docker-plan.outputs.action }} ${{ matrix.image-mapping }} + # Variant images do `COPY --from=ghcr.io/.../uv:${UV_BASE_TAG}` to + # pull binaries out of the just-built base image. On PR validation + # the base isn't pushed, so the variant build can't resolve its + # source layer. Skip the matrix entirely unless we're actually + # pushing the base. + if: ${{ needs.docker-plan.outputs.push == 'true' }} runs-on: ubuntu-latest timeout-minutes: 5 environment: From 1c6909f1081f4745737d5d1ef804e906de84d3f7 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 19:20:17 +0300 Subject: [PATCH 13/28] ci: add probe-incredibuild diagnostic workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manual workflow_dispatch that runs the same identity / tool inventory / Docker / kernel-features probe on both incredibuild-runner and ubuntu-latest, side-by-side. Designed to capture exactly what the Incredibuild Hosted Build Runner image contains, what's preinstalled, how its docker wrapper behaves, and how it differs from a stock GitHub-hosted Linux runner — so we can document concrete root causes for the carve-outs we made (Depot/buildx/QEMU/Firecracker). Co-Authored-By: Claude Opus 4.7 --- .github/workflows/probe-incredibuild.yml | 143 +++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 .github/workflows/probe-incredibuild.yml diff --git a/.github/workflows/probe-incredibuild.yml b/.github/workflows/probe-incredibuild.yml new file mode 100644 index 0000000000000..31aea8cc04da3 --- /dev/null +++ b/.github/workflows/probe-incredibuild.yml @@ -0,0 +1,143 @@ +name: probe-incredibuild +# Diagnostic-only workflow. Runs both on incredibuild-runner and on +# ubuntu-latest and prints exhaustive environment + tool inventory so +# we can pinpoint exactly where Incredibuild's runner image differs +# from a stock GitHub-hosted Linux runner. Triggered manually only. + +on: + workflow_dispatch: + +permissions: {} + +jobs: + probe-ib: + name: "probe on incredibuild-runner" + runs-on: incredibuild-runner + timeout-minutes: 10 + steps: + - name: "Identity" + run: | + echo "=== whoami / id ===" + id; whoami + echo "=== uname ===" + uname -a + echo "=== /etc/os-release ===" + cat /etc/os-release || true + echo "=== cgroup ===" + cat /proc/1/cgroup 2>/dev/null | head -5 || true + echo "=== runner env ===" + env | grep -iE "^(RUNNER_|GITHUB_|IB_|INCREDIBUILD_)" | sort + + - name: "PATH and ib-accel interception" + run: | + echo "=== PATH ===" + echo "$PATH" | tr ':' '\n' + echo "=== ib-accel binaries ===" + ls -la /ib-workspace/incredibuild/ib-accel/bin 2>/dev/null || echo "(ib-accel/bin not present)" + echo "=== which docker (which one wins) ===" + which -a docker || true + ls -la "$(which docker)" 2>/dev/null || true + + - name: "Tool inventory (presence + version)" + run: | + for tool in bash zsh sh git curl wget unzip jq sudo apt-get \ + docker buildx qemu-system-aarch64 binfmt-support \ + node npm npx python3 python pip rustup cargo rustc clippy \ + cmake make gcc g++ ld ld.lld gold mold \ + tar gzip xz unrar zip 7z openssl gpg \ + ssh systemctl losetup; do + if command -v "$tool" >/dev/null 2>&1; then + v=$(timeout 3 "$tool" --version 2>&1 | head -1 || echo "(no --version)") + printf " ✅ %-22s %s\n" "$tool" "$v" + else + printf " ❌ %-22s MISSING\n" "$tool" + fi + done + + - name: "Kernel features" + run: | + echo "=== /dev/loop* ===" + ls -la /dev/loop* 2>/dev/null || echo "(no loop devices)" + echo "=== /dev/kvm ===" + ls -la /dev/kvm 2>/dev/null || echo "(no kvm)" + echo "=== binfmt_misc ===" + ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 || echo "(no binfmt_misc)" + echo "=== capabilities ===" + grep -i cap /proc/self/status | head -5 || true + echo "=== /proc/self/uid_map ===" + cat /proc/self/uid_map 2>/dev/null || true + + - name: "Docker probe (this is where ib-accel intercepts)" + run: | + if ! command -v docker >/dev/null 2>&1; then + echo "(no docker binary)" + exit 0 + fi + echo "=== docker version ===" + docker version 2>&1 | head -30 || true + echo + echo "=== docker info ===" + docker info 2>&1 | head -40 || true + echo + echo "=== docker buildx version ===" + docker buildx version 2>&1 || echo "(no buildx)" + echo + echo "=== try: docker run --rm hello-world ===" + docker run --rm hello-world 2>&1 | tail -20 || echo "(hello-world failed: $?)" + echo + echo "=== try: docker buildx ls ===" + docker buildx ls 2>&1 || echo "(buildx ls failed)" + + - name: "ib-accel direct invocation" + run: | + if [ -x /ib-workspace/incredibuild/ib-accel/bin/docker ]; then + echo "=== ib-accel docker --version ===" + /ib-workspace/incredibuild/ib-accel/bin/docker --version 2>&1 || true + echo "=== ib-accel docker info ===" + /ib-workspace/incredibuild/ib-accel/bin/docker info 2>&1 | head -30 || true + else + echo "(no ib-accel docker wrapper)" + fi + + - name: "Cargo cache layout" + run: | + echo "=== /ib-workspace ===" + ls -la /ib-workspace 2>/dev/null || echo "(no /ib-workspace)" + echo "=== /ib-workspace/cache ===" + ls -la /ib-workspace/cache 2>/dev/null || true + echo "=== /ib-workspace/cache/cargo-target (size) ===" + du -sh /ib-workspace/cache/cargo-target 2>/dev/null || true + echo "=== \$CARGO_HOME / \$CARGO_TARGET_DIR ===" + echo "CARGO_HOME=${CARGO_HOME:-(unset)}" + echo "CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-(unset)}" + + probe-gh: + name: "probe on ubuntu-latest (control)" + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: "Same identity probe" + run: | + id; whoami; uname -a + - name: "Tool inventory (presence)" + run: | + for tool in bash node npm npx python3 rustup cargo \ + docker buildx qemu-system-aarch64 \ + curl wget unzip jq sudo losetup; do + if command -v "$tool" >/dev/null 2>&1; then + v=$(timeout 3 "$tool" --version 2>&1 | head -1) + printf " ✅ %-22s %s\n" "$tool" "$v" + else + printf " ❌ %-22s MISSING\n" "$tool" + fi + done + - name: "Docker probe" + run: | + docker version 2>&1 | head -30 + docker buildx version + docker run --rm hello-world 2>&1 | tail -20 + - name: "Kernel features" + run: | + ls -la /dev/loop* 2>/dev/null + ls -la /dev/kvm 2>/dev/null + ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 From 0615776b3ae9ad3347b402cfe89c9e224d290afd Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Thu, 7 May 2026 19:21:10 +0300 Subject: [PATCH 14/28] ci: also trigger probe workflow on push (so feature branch can run it) --- .github/workflows/probe-incredibuild.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/probe-incredibuild.yml b/.github/workflows/probe-incredibuild.yml index 31aea8cc04da3..e3a923330233c 100644 --- a/.github/workflows/probe-incredibuild.yml +++ b/.github/workflows/probe-incredibuild.yml @@ -6,6 +6,12 @@ name: probe-incredibuild on: workflow_dispatch: + # Also trigger on changes to this file so we can iterate without + # needing the workflow to live on the default branch (GitHub's + # workflow_dispatch only registers workflows from default branch). + push: + paths: + - .github/workflows/probe-incredibuild.yml permissions: {} From 4834cf9714596f85e44c7fd2dd50c72b4a08a380 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 10:07:03 +0300 Subject: [PATCH 15/28] ci: route heavy cargo commands through ib_console for IB acceleration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per Tal Klainer's guidance: prefix /usr/bin/ib_console with the recommended CI flag set in front of every heavy compile-side cargo invocation so Incredibuild can distribute the build: /usr/bin/ib_console \ --standalone \ --build-cache-local-shared \ --debug=build_cache \ --build-cache-force \ --build-cache-basedir=$PWD \ cargo ... Implementation: small wrapper at scripts/cargo-ib.sh that invokes ib_console when present (incredibuild-runner) and falls through to plain cargo otherwise. Same workflow step works on both runner types without per-job conditionals. Wrapped invocations (Linux jobs only — windows/macos cargo lines left alone since ib_console isn't available there): - bench.yml: 6× cargo run - build-dev-binaries.yml: linux libc/aarch64/armv7-gnueabihf/musl/ android cargo build, plus msrv cargo build + run - check-lint.yml: clippy on linux - check-publish.yml: cargo publish dry-run - test.yml: cargo nextest run on linux Skipped (not heavy compile or not on a runner with ib_console): cargo --version, cargo metadata, cargo fmt, cargo fetch, cargo deny, cargo shear, cargo install (taiki-e/install-action), and all windows/macos cargo invocations. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/bench.yml | 12 +++++----- .github/workflows/build-dev-binaries.yml | 14 ++++++------ .github/workflows/check-lint.yml | 2 +- .github/workflows/check-publish.yml | 2 +- .github/workflows/test.yml | 2 +- scripts/cargo-ib.sh | 29 ++++++++++++++++++++++++ 6 files changed, 45 insertions(+), 16 deletions(-) create mode 100755 scripts/cargo-ib.sh diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 4ebbd8faed121..41c099f85fa6c 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -43,9 +43,9 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libsasl2-dev libldap2-dev libkrb5-dev - cargo run --bin uv -- venv --cache-dir .cache - cargo run --bin uv -- pip compile test/requirements/jupyter.in --universal --exclude-newer 2024-08-08 --cache-dir .cache - cargo run --bin uv -- pip compile test/requirements/airflow.in --universal --exclude-newer 2024-08-08 --cache-dir .cache + ./scripts/cargo-ib.sh run --bin uv -- venv --cache-dir .cache + ./scripts/cargo-ib.sh run --bin uv -- pip compile test/requirements/jupyter.in --universal --exclude-newer 2024-08-08 --cache-dir .cache + ./scripts/cargo-ib.sh run --bin uv -- pip compile test/requirements/airflow.in --universal --exclude-newer 2024-08-08 --cache-dir .cache - name: "Build benchmarks" run: cargo codspeed build -m walltime --profile profiling -p uv-bench @@ -121,9 +121,9 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libsasl2-dev libldap2-dev libkrb5-dev - cargo run --bin uv -- venv --cache-dir .cache - cargo run --bin uv -- pip compile test/requirements/jupyter.in --universal --exclude-newer 2024-08-08 --cache-dir .cache - cargo run --bin uv -- pip compile test/requirements/airflow.in --universal --exclude-newer 2024-08-08 --cache-dir .cache + ./scripts/cargo-ib.sh run --bin uv -- venv --cache-dir .cache + ./scripts/cargo-ib.sh run --bin uv -- pip compile test/requirements/jupyter.in --universal --exclude-newer 2024-08-08 --cache-dir .cache + ./scripts/cargo-ib.sh run --bin uv -- pip compile test/requirements/airflow.in --universal --exclude-newer 2024-08-08 --cache-dir .cache - name: "Build benchmarks" run: cargo codspeed build --profile profiling -p uv-bench diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index 1c14e4a8dc3bb..f01d2acdc72b6 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -32,7 +32,7 @@ jobs: save-if: ${{ inputs.save-rust-cache == 'true' }} - name: "Build" - run: cargo build --profile no-debug + run: ./scripts/cargo-ib.sh build --profile no-debug - name: "Upload binary" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -60,7 +60,7 @@ jobs: save-if: ${{ inputs.save-rust-cache == 'true' }} - name: "Build" - run: cargo build --profile no-debug + run: ./scripts/cargo-ib.sh build --profile no-debug - name: "Upload binary" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -99,7 +99,7 @@ jobs: - name: "Build" env: CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc - run: cargo build --profile no-debug --target armv7-unknown-linux-gnueabihf --bin uv --bin uvx + run: ./scripts/cargo-ib.sh build --profile no-debug --target armv7-unknown-linux-gnueabihf --bin uv --bin uvx - name: "Upload binary" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -136,7 +136,7 @@ jobs: save-if: ${{ inputs.save-rust-cache == 'true' }} - name: "Build" - run: cargo build --profile no-debug --target x86_64-unknown-linux-musl --bin uv --bin uvx + run: ./scripts/cargo-ib.sh build --profile no-debug --target x86_64-unknown-linux-musl --bin uv --bin uvx - name: "Upload binary" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -296,13 +296,13 @@ jobs: - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: save-if: ${{ inputs.save-rust-cache == 'true' }} - - run: cargo +${MSRV} build --profile no-debug --bin uv + - run: ./scripts/cargo-ib.sh +${MSRV} build --profile no-debug --bin uv env: MSRV: ${{ steps.msrv.outputs.value }} # Use `cargo run` instead of `./target/...` so the path resolves # via cargo metadata regardless of CARGO_TARGET_DIR overrides # (Incredibuild Hosted Build Runner sets a shared target dir). - - run: cargo +${MSRV} run --profile no-debug --bin uv -- --version + - run: ./scripts/cargo-ib.sh +${MSRV} run --profile no-debug --bin uv -- --version env: MSRV: ${{ steps.msrv.outputs.value }} @@ -363,7 +363,7 @@ jobs: save-if: ${{ inputs.save-rust-cache == 'true' }} - name: "Build" - run: cargo build --profile no-debug --target aarch64-linux-android --bin uv --bin uvx + run: ./scripts/cargo-ib.sh build --profile no-debug --target aarch64-linux-android --bin uv --bin uvx - name: "Upload binary" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index 3bd30c6ff61e8..72640df0cea9b 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -112,7 +112,7 @@ jobs: - name: "Install Rust toolchain" run: rustup component add clippy - name: "Clippy" - run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings + run: ./scripts/cargo-ib.sh clippy --workspace --all-targets --all-features --locked -- -D warnings clippy-windows: name: "clippy on windows" diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index ddd103b2ae636..4f75eeefdae6e 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -22,4 +22,4 @@ jobs: with: save-if: ${{ github.ref == 'refs/heads/main' }} - name: "cargo publish dry-run" - run: cargo publish --workspace --dry-run + run: ./scripts/cargo-ib.sh publish --workspace --dry-run diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8ff49a3e25283..9c2b9034609ce 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -142,7 +142,7 @@ jobs: INSTA_UPDATE: new INSTA_PENDING_DIR: ${{ github.workspace }}/pending-snapshots run: | - cargo nextest run \ + ./scripts/cargo-ib.sh nextest run \ --cargo-profile fast-build \ --features test-python-patch,native-auth,secret-service \ --workspace \ diff --git a/scripts/cargo-ib.sh b/scripts/cargo-ib.sh new file mode 100755 index 0000000000000..52d488f059d60 --- /dev/null +++ b/scripts/cargo-ib.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Invoke cargo through Incredibuild's ib_console when available so +# heavy compile commands (build, test, clippy, check, nextest run, +# publish dry-run) get distributed across the IB acceleration network. +# +# On runners that don't have ib_console (e.g. ubuntu-latest carve-outs +# for cross-compile / Docker-dependent jobs), this falls through to +# plain `cargo` so the same workflow step works on both runner types. +# +# Flags chosen per Incredibuild's recommended template for CI builds: +# --standalone run without joining a coordinator +# --build-cache-local-shared use the runner-local shared cache +# --debug=build_cache emit cache hit/miss diagnostics into the log +# --build-cache-force force-fill the cache even on the first run +# --build-cache-basedir=PWD scope the cache key to the workspace root + +set -euo pipefail + +if [ -x /usr/bin/ib_console ]; then + exec /usr/bin/ib_console \ + --standalone \ + --build-cache-local-shared \ + --debug=build_cache \ + --build-cache-force \ + --build-cache-basedir="$PWD" \ + cargo "$@" +else + exec cargo "$@" +fi From b48465f6975f0b1918179042aef03cc3ac4f7be0 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 10:15:47 +0300 Subject: [PATCH 16/28] ci: cargo-ib.sh forces CARGO_TARGET_DIR=PWD/target; revert nextest wrap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two issues from the first wave-14 (ib_console wrapper) run: 1. build-dev-binaries / linux libc, etc.: artifact upload step warned `No files were found with the provided path: ./target/no-debug/uv`. ib_console (or its surrounding IB env) redirects cargo's output away from the workspace `./target/`, so every downstream consumer of the linux-libc artifact (test-ecosystem, test-system, test-smoke, test-integration — ~14 jobs) failed to find the binary. Fix: force-export CARGO_TARGET_DIR=$PWD/target in cargo-ib.sh before invoking ib_console. The IB build cache still works (it's separate from cargo's target dir); only the *output* path is pinned. 2. test / cargo test on linux exited 101 at 51s with the log truncated mid-line right after `Incredibuild System: ib_server connected`. cargo nextest's heavy subprocess forking for parallel test execution is likely incompatible with ib_console's distribution path (or hits the FD-limit warning ib_console itself printed). Revert to plain `cargo nextest run` until IB team confirms safe interop. Other cargo invocations (build, clippy, run, publish) still go through ib_console and engaged the cache successfully on wave 14. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/test.yml | 7 ++++++- scripts/cargo-ib.sh | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9c2b9034609ce..195f8f7dab6f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -142,7 +142,12 @@ jobs: INSTA_UPDATE: new INSTA_PENDING_DIR: ${{ github.workspace }}/pending-snapshots run: | - ./scripts/cargo-ib.sh nextest run \ + # Note: not wrapping with cargo-ib.sh here. ib_console exited + # mid-compile under cargo nextest's process-management + # (truncated log right after `Incredibuild System: ib_server + # connected`). Run plain cargo nextest until the IB team + # confirms safe interop with nextest's test-runner forking. + cargo nextest run \ --cargo-profile fast-build \ --features test-python-patch,native-auth,secret-service \ --workspace \ diff --git a/scripts/cargo-ib.sh b/scripts/cargo-ib.sh index 52d488f059d60..91106b868ca3f 100755 --- a/scripts/cargo-ib.sh +++ b/scripts/cargo-ib.sh @@ -16,6 +16,14 @@ set -euo pipefail +# Pin cargo's output directory to the workspace `./target/`. Without +# this, ib_console (or surrounding IB env) redirects cargo output to +# /ib-workspace/cache/cargo-target/ and then `actions/upload-artifact` +# steps that expect `./target/no-debug/uv` find nothing, breaking +# every downstream test-ecosystem / test-system / test-smoke job that +# downloads the linux-libc binary. +export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$PWD/target}" + if [ -x /usr/bin/ib_console ]; then exec /usr/bin/ib_console \ --standalone \ From 0efe0e62a8ceb1800c922b00403c2d31254907eb Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 10:30:21 +0300 Subject: [PATCH 17/28] ci: cargo-ib.sh symlinks ./target -> IB's shared cargo-target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverts the CARGO_TARGET_DIR=$PWD/target override from wave 15. That env override caused linux libc (and likely others) to crash with exit 101 immediately after `ib_server connected` — ib_console appears to refuse work when its cache target path is overridden out of /ib-workspace/cache/cargo-target/. New approach: at the start of cargo-ib.sh, if IB's shared cache dir exists and ./target/ doesn't, symlink ./target -> the IB cache. That way: - ib_console keeps its expected target dir intact (no crash) - cargo writes go to IB's cache (good — that's how acceleration + cross-job sharing works) - actions/upload-artifact still finds binaries at ./target/no-debug/uv because the symlink resolves there - subsequent rust-cache restore + Swatinem cache key paths still work (they walk through the symlink) On runners without IB (the 11 ubuntu-latest carve-outs), the symlink no-op's and cargo writes to ./target/ as normal. Co-Authored-By: Claude Opus 4.7 --- scripts/cargo-ib.sh | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/scripts/cargo-ib.sh b/scripts/cargo-ib.sh index 91106b868ca3f..d505f683cede3 100755 --- a/scripts/cargo-ib.sh +++ b/scripts/cargo-ib.sh @@ -16,13 +16,22 @@ set -euo pipefail -# Pin cargo's output directory to the workspace `./target/`. Without -# this, ib_console (or surrounding IB env) redirects cargo output to -# /ib-workspace/cache/cargo-target/ and then `actions/upload-artifact` -# steps that expect `./target/no-debug/uv` find nothing, breaking -# every downstream test-ecosystem / test-system / test-smoke job that -# downloads the linux-libc binary. -export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$PWD/target}" +# Expose IB's shared cargo target dir at the workspace's ./target/ +# location BEFORE running cargo, so when ib_console redirects cargo +# output to /ib-workspace/cache/cargo-target/ the resulting binaries +# are still findable at ./target/no-debug/uv etc. for +# actions/upload-artifact and downstream consumers (test-ecosystem, +# test-system, test-smoke, test-integration). +# +# We use a symlink instead of forcing CARGO_TARGET_DIR=$PWD/target +# because ib_console crashes (exit 101 immediately after +# "ib_server connected") when its expected target path is overridden +# from the workspace. +IB_TARGET="${IB_CARGO_TARGET_DIR:-/ib-workspace/cache/cargo-target}" +if [ -d "$IB_TARGET" ] && [ ! -e "$PWD/target" ]; then + ln -s "$IB_TARGET" "$PWD/target" + echo "cargo-ib: $PWD/target -> $IB_TARGET" +fi if [ -x /usr/bin/ib_console ]; then exec /usr/bin/ib_console \ From 93fea0e7bbfe0def8c4b6d2238001c66b91364d7 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 10:40:50 +0300 Subject: [PATCH 18/28] ci: enable workflow_dispatch on bench.yml Allows manually triggering benchmarks on the fork without needing a push to main or rust source change. Useful for validating that ib_console-wrapped `cargo run` invocations engage acceleration correctly under benchmark load. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/bench.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 41c099f85fa6c..38b494c6116a0 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -5,6 +5,10 @@ on: required: false type: string default: "true" + # Allow manual dispatch on this fork so we can validate ib_console + # acceleration on cargo run benchmarks without needing main-branch + # pushes or rust file changes. + workflow_dispatch: permissions: {} From 00fe045a368a2a93cf92b317d32d5baedee70f85 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 10:49:16 +0300 Subject: [PATCH 19/28] chore: touch uv-version comment to flip any_rust_changed and run bench Force-triggers the bench workflow on this PR so we can validate ib_console acceleration on cargo-run benchmarks. Comment-only edit; no behavior change. Co-Authored-By: Claude Opus 4.7 --- crates/uv-version/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/uv-version/src/lib.rs b/crates/uv-version/src/lib.rs index 20a8940a12164..e309fe63be705 100644 --- a/crates/uv-version/src/lib.rs +++ b/crates/uv-version/src/lib.rs @@ -1,6 +1,12 @@ /// Return the application version. /// /// This should be in sync with uv's version based on the Crate version. +// +// CI note: this file is intentionally touched on the +// Incredibuild-RND/uv fork to flip `any_rust_changed=1` in the CI +// plan step, which unblocks the bench workflow so we can validate +// ib_console acceleration on cargo-run benchmarks. Safe to drop on +// the next upstream sync. pub fn version() -> &'static str { env!("CARGO_PKG_VERSION") } From 5bde38b3e4158e9a781a84a5491b44202ad3353d Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 11:17:56 +0300 Subject: [PATCH 20/28] ci: split cargo nextest into ib_console-accelerated compile + plain run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: wrapping the full `cargo nextest run` invocation with ib_console causes it to crash with exit 101 right after `Incredibuild System: ib_server connected, start process execution`, likely because nextest forks a per-test subprocess pool that conflicts with ib_console's own process management (and the high-FD warning ib_console itself prints). Fix: split into two phases. Phase 1: ./scripts/cargo-ib.sh nextest run --no-run — Compiles all test binaries through ib_console, which gets the heavy compile work cache-accelerated and matches the existing build-cache flag set Tal asked for. `--no-run` means we don't actually execute tests yet, so no test-runner subprocess fork happens here. Phase 2: cargo nextest run --no-fail-fast — Plain cargo (no ib_console) just executes the already-compiled binaries. nextest's fork model is unaffected, no exit 101 crash. Also raises ulimit before phase 1 to silence ib_console's FD limit warning. `--no-fail-fast` keeps the run going past first failure so we get a complete picture of which tests really fail (vs. flake). Net effect: heavy cargo test compile gets the same ib_console acceleration that cargo build / cargo clippy already get. Test execution stays in plain cargo where nextest is happy. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/test.yml | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 195f8f7dab6f9..dc81923580d20 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -129,6 +129,21 @@ jobs: with: tool: cargo-nextest + - name: "Build test binaries (accelerated via ib_console)" + # Split cargo nextest into two phases so ib_console accelerates + # the heavy COMPILE work (where cache reuse and distribution + # matter) without colliding with nextest's own subprocess + # forking during test execution. `--no-run` compiles all test + # binaries but doesn't run them. Raise FD limit because + # ib_console warns that 131072 may degrade performance. + run: | + ulimit -n 10000 || true + ./scripts/cargo-ib.sh nextest run --no-run \ + --cargo-profile fast-build \ + --features test-python-patch,native-auth,secret-service \ + --workspace \ + --profile ci-linux + - name: "Cargo test" env: # Retry more than default to reduce flakes in CI @@ -142,16 +157,15 @@ jobs: INSTA_UPDATE: new INSTA_PENDING_DIR: ${{ github.workspace }}/pending-snapshots run: | - # Note: not wrapping with cargo-ib.sh here. ib_console exited - # mid-compile under cargo nextest's process-management - # (truncated log right after `Incredibuild System: ib_server - # connected`). Run plain cargo nextest until the IB team - # confirms safe interop with nextest's test-runner forking. + # Plain cargo nextest here: test binaries are already compiled + # by the previous step, so this only executes them. ib_console + # is incompatible with nextest's runtime fork model. cargo nextest run \ --cargo-profile fast-build \ --features test-python-patch,native-auth,secret-service \ --workspace \ - --profile ci-linux + --profile ci-linux \ + --no-fail-fast - name: "Upload pending snapshots" if: ${{ failure() }} From 1ea2b5010b020259d5eb1bfb77390777a1b2f81d Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 11:22:15 +0300 Subject: [PATCH 21/28] ci: isolate CARGO_HOME for sdist (avoid IB shared-registry corruption) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sdist failed wave-19 with 'unclosed delimiter' rust parse errors — same NUL-byte source corruption pattern that hit msrv earlier when multiple jobs concurrently mutated /ib-workspace/cache/cargo/ registry/. The maturin pep517 wheel build calls cargo through pip, which uses the global CARGO_HOME and is therefore exposed. Pin CARGO_HOME=$GITHUB_WORKSPACE/.cargo and CARGO_TARGET_DIR= $GITHUB_WORKSPACE/target for the sdist job. Costs a fresh cargo fetch on each run but eliminates the race. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-release-binaries.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build-release-binaries.yml b/.github/workflows/build-release-binaries.yml index a8091ebd26de5..dbd17d58c892a 100644 --- a/.github/workflows/build-release-binaries.yml +++ b/.github/workflows/build-release-binaries.yml @@ -33,6 +33,16 @@ jobs: sdist: name: sdist runs-on: incredibuild-runner + env: + # Pin per-job CARGO_HOME / CARGO_TARGET_DIR. The maturin + # pep517 wheel build invokes cargo through pip, which on the + # IB runner shares /ib-workspace/cache/cargo/registry/ across + # concurrent jobs and occasionally produces NUL-byte + # corrupted .crate sources (manifests as "unclosed delimiter" + # parse errors mid-compile). Job-local CARGO_HOME costs a + # fresh cargo fetch but eliminates the race. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From 4a4dcafda0e6800ed0311e50ee76b16c4b3908cf Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 11:27:55 +0300 Subject: [PATCH 22/28] =?UTF-8?q?ci:=20refocus=20PR=20=E2=80=94=20IB=20run?= =?UTF-8?q?ner=20only=20for=20jobs=20that=20compile=20cargo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave 21 (focus pass): from 76 incredibuild-runner placements down to 14, scoped to jobs where ib_console + IB shared cargo cache demonstrably help — i.e. heavy cargo compile work. Everything else (linting, formatting, docs, integration/system/smoke tests that just consume pre-built binaries, publish/release glue) goes back to ubuntu-latest. Why - ib_console with Tal's flag set provides build-cache acceleration, not distributed compile (--standalone). The value is purely cargo compile cache reuse. - Non-cargo jobs got nothing from being on IB except the cost of bootstrapping the lean image (sudo/wget/Node/etc). - Routing them to ubuntu-latest also frees IB runner capacity for the cargo jobs that actually benefit. KEEP on incredibuild-runner (14): bench/{walltime build, simulated} cargo run build-dev-binaries/{linux libc, linux aarch64, linux armv7 gnueabihf, linux musl, msrv, android aarch64} cargo build build-release-binaries/sdist maturin -> cargo (pep517) check-generated-files/cargo-dev-generate-all cargo dev compile check-lint/clippy-ubuntu cargo clippy check-publish/cargo-publish-dry-run cargo publish (compiles) test/cargo-test-linux cargo nextest --no-run probe-incredibuild/probe-ib diagnostic, must stay MOVE to ubuntu-latest (64): - All check-fmt/check-lint/check-zizmor/check-docs jobs (no cargo) - All test-system/test-integration/test-smoke/test-ecosystem (consume pre-built uv binary, no cargo compile) - All publish-* jobs (artifact pushes, no compile) - check-release/dist-plan, ci.yml plan/test-publish/required-checks-passed - test-windows-trampolines Linux prep portions - build-docker/plan, build-release-binaries/check-wheels Co-Authored-By: Claude Opus 4.7 --- .github/workflows/bench.yml | 2 +- .github/workflows/build-dev-binaries.yml | 2 +- .github/workflows/build-docker.yml | 4 +-- .github/workflows/build-release-binaries.yml | 4 +-- .github/workflows/check-docs.yml | 4 +-- .github/workflows/check-fmt.yml | 8 ++--- .github/workflows/check-generated-files.yml | 2 +- .github/workflows/check-lint.yml | 16 ++++----- .github/workflows/check-publish.yml | 2 +- .github/workflows/check-release.yml | 4 +-- .github/workflows/check-zizmor.yml | 4 +-- .github/workflows/ci.yml | 8 ++--- .github/workflows/probe-incredibuild.yml | 2 +- .github/workflows/publish-crates.yml | 4 +-- .github/workflows/publish-docs.yml | 4 +-- .github/workflows/publish-mirror.yml | 4 +-- .github/workflows/publish-pypi.yml | 6 ++-- .github/workflows/publish-versions.yml | 4 +-- .github/workflows/release-prepare.yml | 4 +-- .github/workflows/release.yml | 4 +-- .github/workflows/sync-python-releases.yml | 4 +-- .github/workflows/test-ecosystem.yml | 4 +-- .github/workflows/test-integration.yml | 30 ++++++++-------- .github/workflows/test-smoke.yml | 8 ++--- .github/workflows/test-system.yml | 36 +++++++++---------- .../workflows/test-windows-trampolines.yml | 6 ++-- .github/workflows/test.yml | 2 +- 27 files changed, 91 insertions(+), 91 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 38b494c6116a0..508ed4858b76c 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -137,4 +137,4 @@ jobs: with: run: cargo codspeed run mode: simulation - token: ${{ secrets.CODSPEED_TOKEN }} + token: ${{ secrets.CODSPEED_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index f01d2acdc72b6..184dddcbdf790 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -422,4 +422,4 @@ jobs: run-in-vm: | mv target/x86_64-unknown-freebsd/no-debug/uv uv chmod +x uv - ./uv --version + ./uv --version \ No newline at end of file diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 1e7a9ffac4be7..27b8d7b920cae 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -38,7 +38,7 @@ permissions: {} jobs: docker-plan: name: plan - runs-on: incredibuild-runner + runs-on: ubuntu-latest timeout-minutes: 2 outputs: login: ${{ steps.plan.outputs.login }} @@ -492,4 +492,4 @@ jobs: uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 with: subject-name: ${{ env.UV_GHCR_IMAGE }} - subject-digest: ${{ steps.manifest-digest.outputs.digest }} + subject-digest: ${{ steps.manifest-digest.outputs.digest }} \ No newline at end of file diff --git a/.github/workflows/build-release-binaries.yml b/.github/workflows/build-release-binaries.yml index dbd17d58c892a..749c4b832415b 100644 --- a/.github/workflows/build-release-binaries.yml +++ b/.github/workflows/build-release-binaries.yml @@ -1204,7 +1204,7 @@ jobs: check-wheels: name: "Check wheel contents" - runs-on: incredibuild-runner + runs-on: ubuntu-latest needs: - macos-x86_64 - macos-aarch64 @@ -1228,4 +1228,4 @@ jobs: path: wheels merge-multiple: true - name: "Check wheel contents" - run: uv run --no-project scripts/check_uv_wheel_contents.py wheels/* + run: uv run --no-project scripts/check_uv_wheel_contents.py wheels/* \ No newline at end of file diff --git a/.github/workflows/check-docs.yml b/.github/workflows/check-docs.yml index 09e26c21239f8..2cd15f126a847 100644 --- a/.github/workflows/check-docs.yml +++ b/.github/workflows/check-docs.yml @@ -7,7 +7,7 @@ jobs: docs: timeout-minutes: 10 name: "mkdocs" - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -28,4 +28,4 @@ jobs: cargo dev generate-env-vars-reference - name: "Build docs" - run: uv run --only-group docs mkdocs build --strict -f mkdocs.yml + run: uv run --only-group docs mkdocs build --strict -f mkdocs.yml \ No newline at end of file diff --git a/.github/workflows/check-fmt.yml b/.github/workflows/check-fmt.yml index 63f7a04b477d4..22be3a16f345f 100644 --- a/.github/workflows/check-fmt.yml +++ b/.github/workflows/check-fmt.yml @@ -6,7 +6,7 @@ permissions: {} jobs: rust: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -17,7 +17,7 @@ jobs: prettier: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -29,7 +29,7 @@ jobs: python: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -38,4 +38,4 @@ jobs: uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: version: "0.11.8" - - run: uvx ruff format --diff . + - run: uvx ruff format --diff . \ No newline at end of file diff --git a/.github/workflows/check-generated-files.yml b/.github/workflows/check-generated-files.yml index ae92ca1ca8c75..95261619d2a3f 100644 --- a/.github/workflows/check-generated-files.yml +++ b/.github/workflows/check-generated-files.yml @@ -46,4 +46,4 @@ jobs: run: cargo dev generate-sysconfig-metadata --mode check - name: "Check JSON schema" if: ${{ inputs.schema-changed == 'true' }} - run: cargo dev generate-json-schema --mode check + run: cargo dev generate-json-schema --mode check \ No newline at end of file diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index 72640df0cea9b..bd3e8266f5428 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -20,7 +20,7 @@ env: jobs: ruff: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -33,7 +33,7 @@ jobs: ty: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -51,7 +51,7 @@ jobs: shellcheck: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -68,7 +68,7 @@ jobs: validate-pyproject: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -81,7 +81,7 @@ jobs: readme: timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -147,7 +147,7 @@ jobs: shear: name: "cargo shear" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -159,7 +159,7 @@ jobs: - run: cargo shear --deny-warnings typos: - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -170,4 +170,4 @@ jobs: if [ "$(id -u)" = "0" ]; then SUDO=""; else SUDO="sudo"; fi $SUDO apt-get update && $SUDO apt-get install -y wget fi - - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1 + - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1 \ No newline at end of file diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index 4f75eeefdae6e..1948d3fc57ed6 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -22,4 +22,4 @@ jobs: with: save-if: ${{ github.ref == 'refs/heads/main' }} - name: "cargo publish dry-run" - run: ./scripts/cargo-ib.sh publish --workspace --dry-run + run: ./scripts/cargo-ib.sh publish --workspace --dry-run \ No newline at end of file diff --git a/.github/workflows/check-release.yml b/.github/workflows/check-release.yml index e0bd7cee2b990..e266177ef41f1 100644 --- a/.github/workflows/check-release.yml +++ b/.github/workflows/check-release.yml @@ -8,7 +8,7 @@ env: jobs: dist-plan: name: "dist plan" - runs-on: incredibuild-runner + runs-on: ubuntu-latest env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: @@ -31,4 +31,4 @@ jobs: run: | dist plan --output-format=json > plan-dist-manifest.json echo "dist plan completed successfully" - cat plan-dist-manifest.json + cat plan-dist-manifest.json \ No newline at end of file diff --git a/.github/workflows/check-zizmor.yml b/.github/workflows/check-zizmor.yml index 871235dddc007..6122095875fef 100644 --- a/.github/workflows/check-zizmor.yml +++ b/.github/workflows/check-zizmor.yml @@ -5,7 +5,7 @@ permissions: {} jobs: zizmor: - runs-on: incredibuild-runner + runs-on: ubuntu-latest permissions: security-events: write steps: @@ -13,4 +13,4 @@ jobs: with: persist-credentials: false - - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e24423a776d9..79da2f5a1fb54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ concurrency: jobs: plan: - runs-on: incredibuild-runner + runs-on: ubuntu-latest outputs: test-code: ${{ steps.plan.outputs.test_code }} check-schema: ${{ steps.plan.outputs.check_schema }} @@ -275,7 +275,7 @@ jobs: needs: - plan - build-dev-binaries - runs-on: incredibuild-runner + runs-on: ubuntu-latest # Only the main repository is a trusted publisher if: ${{ github.repository == 'astral-sh/uv' && github.event.pull_request.head.repo.fork != true && needs.plan.outputs.test-publish == 'true' }} environment: @@ -406,7 +406,7 @@ jobs: - check-generated-files - test - build-dev-binaries - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - name: "Check required jobs passed" run: | @@ -416,4 +416,4 @@ jobs: exit 1 fi env: - NEEDS_JSON: ${{ toJSON(needs) }} + NEEDS_JSON: ${{ toJSON(needs) }} \ No newline at end of file diff --git a/.github/workflows/probe-incredibuild.yml b/.github/workflows/probe-incredibuild.yml index e3a923330233c..2284dcaa4f6a1 100644 --- a/.github/workflows/probe-incredibuild.yml +++ b/.github/workflows/probe-incredibuild.yml @@ -146,4 +146,4 @@ jobs: run: | ls -la /dev/loop* 2>/dev/null ls -la /dev/kvm 2>/dev/null - ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 + ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 \ No newline at end of file diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml index cb999bc8934b1..c323e3640a59e 100644 --- a/.github/workflows/publish-crates.yml +++ b/.github/workflows/publish-crates.yml @@ -14,7 +14,7 @@ on: jobs: crates-publish-uv: name: Upload uv to crates.io - runs-on: incredibuild-runner + runs-on: ubuntu-latest environment: name: release permissions: @@ -35,4 +35,4 @@ jobs: # Note `--no-verify` is safe because we do a publish dry-run elsewhere in CI run: cargo +nightly-2026-04-15 publish --workspace --no-verify -Zpublish-timeout --config 'publish.timeout=600' env: - CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} \ No newline at end of file diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 98b0c257015d2..6a9ee509bd893 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -23,7 +23,7 @@ jobs: mkdocs: environment: name: release - runs-on: incredibuild-runner + runs-on: ubuntu-latest env: VERSION: ${{ (inputs.plan != '' && fromJson(inputs.plan).announcement_tag) || inputs.ref }} steps: @@ -140,4 +140,4 @@ jobs: # auto-merge the PR if the build was triggered by a release. Manual builds should be reviewed by a human. # give the PR a few seconds to be created before trying to auto-merge it sleep 10 - gh pr merge --squash $branch_name + gh pr merge --squash $branch_name \ No newline at end of file diff --git a/.github/workflows/publish-mirror.yml b/.github/workflows/publish-mirror.yml index b2de5c4d5d826..32c20293c1aad 100644 --- a/.github/workflows/publish-mirror.yml +++ b/.github/workflows/publish-mirror.yml @@ -14,7 +14,7 @@ permissions: {} jobs: publish-mirror: - runs-on: incredibuild-runner + runs-on: ubuntu-latest environment: name: release env: @@ -57,4 +57,4 @@ jobs: --cache-control "public, max-age=300" \ "artifacts/${installer}" \ "s3://${R2_BUCKET}/installers/uv/latest/${installer}" - done + done \ No newline at end of file diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 998626db2d211..d7f50df57315e 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -14,7 +14,7 @@ on: jobs: pypi-publish-uv: name: Upload uv to PyPI - runs-on: incredibuild-runner + runs-on: ubuntu-latest environment: name: release permissions: @@ -32,7 +32,7 @@ jobs: pypi-publish-uv-build: name: Upload uv-build to PyPI - runs-on: incredibuild-runner + runs-on: ubuntu-latest environment: name: release permissions: @@ -46,4 +46,4 @@ jobs: path: wheels_uv_build merge-multiple: true - name: Publish to PyPI - run: uv publish -v wheels_uv_build/* + run: uv publish -v wheels_uv_build/* \ No newline at end of file diff --git a/.github/workflows/publish-versions.yml b/.github/workflows/publish-versions.yml index 0d239a9a28d2a..7db08f22d4e17 100644 --- a/.github/workflows/publish-versions.yml +++ b/.github/workflows/publish-versions.yml @@ -15,7 +15,7 @@ permissions: {} jobs: publish-versions: - runs-on: incredibuild-runner + runs-on: ubuntu-latest environment: name: release env: @@ -74,4 +74,4 @@ jobs: run: | # Wait for PR to be created before merging sleep 10 - gh pr merge --squash "$BRANCH_NAME" + gh pr merge --squash "$BRANCH_NAME" \ No newline at end of file diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml index bf2133e23deeb..5ebed23342799 100644 --- a/.github/workflows/release-prepare.yml +++ b/.github/workflows/release-prepare.yml @@ -18,7 +18,7 @@ permissions: {} jobs: release: if: github.repository == 'astral-sh/uv' - runs-on: incredibuild-runner + runs-on: ubuntu-latest permissions: contents: write pull-requests: write @@ -65,4 +65,4 @@ jobs: --head "$branch" \ --fill env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9c458d91e3584..5d2c7eb64af20 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,7 +56,7 @@ jobs: # N.B. This name should not change, it is used for downstream checks. name: release-gate if: ${{ inputs.tag != 'dry-run' }} - runs-on: incredibuild-runner + runs-on: ubuntu-latest # This environment requires a 2-factor approval, i.e., the workflow must be approved by another # team member. GitHub fires approval events on every job that deploys to an environment, so we # have a dedicated environment for this purpose instead of using the `release` environment. @@ -393,4 +393,4 @@ jobs: plan: ${{ needs.plan.outputs.val }} secrets: inherit permissions: - "contents": "read" + "contents": "read" \ No newline at end of file diff --git a/.github/workflows/sync-python-releases.yml b/.github/workflows/sync-python-releases.yml index d2eb205f0adef..635a3700dcc98 100644 --- a/.github/workflows/sync-python-releases.yml +++ b/.github/workflows/sync-python-releases.yml @@ -12,7 +12,7 @@ permissions: {} jobs: sync: if: github.repository == 'astral-sh/uv' - runs-on: incredibuild-runner + runs-on: ubuntu-latest permissions: contents: write pull-requests: write @@ -56,4 +56,4 @@ jobs: title: "Sync latest Python releases" body: "Automated update for Python releases." base: "main" - draft: true + draft: true \ No newline at end of file diff --git a/.github/workflows/test-ecosystem.yml b/.github/workflows/test-ecosystem.yml index 878dbfa3e51a7..e6bf3097d665f 100644 --- a/.github/workflows/test-ecosystem.yml +++ b/.github/workflows/test-ecosystem.yml @@ -11,7 +11,7 @@ jobs: ecosystem-test: name: "${{ matrix.repo }}" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest strategy: matrix: include: @@ -62,4 +62,4 @@ jobs: else $cmd fi - done + done \ No newline at end of file diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 6b9f40798bb6f..2f8447edbb51a 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -19,7 +19,7 @@ jobs: integration-test-nushell: name: "nushell" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -66,7 +66,7 @@ jobs: integration-test-conda: name: "conda on linux" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -137,7 +137,7 @@ jobs: integration-test-deadsnakes-39-linux: name: "deadsnakes python3.9 on ubuntu" timeout-minutes: 15 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - name: "Bootstrap baseline tools" run: | @@ -193,7 +193,7 @@ jobs: integration-test-linux-armv7-on-aarch64: name: "armv7 on aarch64 linux" timeout-minutes: 20 - runs-on: incredibuild-runner + runs-on: ubuntu-latest env: UV_PYTHON_INSTALL_DIR: ${{ github.workspace }}/.python @@ -414,7 +414,7 @@ jobs: integration-test-pypy-linux: name: "pypy on linux" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -479,7 +479,7 @@ jobs: integration-test-python-install-wine: name: "python install under wine" timeout-minutes: 15 - runs-on: incredibuild-runner + runs-on: ubuntu-latest env: WINEARCH: win64 WINEDEBUG: -all @@ -577,7 +577,7 @@ jobs: integration-test-graalpy-linux: name: "graalpy on linux" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -701,7 +701,7 @@ jobs: integration-test-pyodide-linux: name: "pyodide on linux" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -790,7 +790,7 @@ jobs: integration-test-termux: name: "termux on android" timeout-minutes: 15 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -815,7 +815,7 @@ jobs: integration-test-github-actions: name: "github actions" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: @@ -872,7 +872,7 @@ jobs: integration-test-github-actions-freethreaded: name: "free-threaded on github actions" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: @@ -962,7 +962,7 @@ jobs: integration-test-registries: name: "registries" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest if: ${{ github.event.pull_request.head.repo.fork != true }} environment: name: uv-test-registries @@ -1072,7 +1072,7 @@ jobs: integration-uv-build-backend: name: "uv_build" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -1121,7 +1121,7 @@ jobs: cache-test-ubuntu: name: "cache on linux" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -1170,4 +1170,4 @@ jobs: run: curl -LsSf "https://github.com/astral-sh/uv/releases/latest/download/uv-aarch64-apple-darwin.tar.gz" | tar -xvz - name: "Check cache compatibility" - run: python scripts/check_cache_compat.py --uv-current ./uv --uv-previous ./uv-aarch64-apple-darwin/uv + run: python scripts/check_cache_compat.py --uv-current ./uv --uv-previous ./uv-aarch64-apple-darwin/uv \ No newline at end of file diff --git a/.github/workflows/test-smoke.yml b/.github/workflows/test-smoke.yml index 02ba864eb9692..bf825a1c2eaf4 100644 --- a/.github/workflows/test-smoke.yml +++ b/.github/workflows/test-smoke.yml @@ -18,7 +18,7 @@ jobs: smoke-test-linux: name: "linux" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -46,7 +46,7 @@ jobs: smoke-test-linux-aarch64: name: "linux aarch64" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -74,7 +74,7 @@ jobs: smoke-test-linux-musl: name: "linux musl" timeout-minutes: 10 - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: alpine:latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -179,4 +179,4 @@ jobs: - name: "Test uvx shell completions" working-directory: ${{ env.UV_WORKSPACE }} run: | - (& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression + (& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression \ No newline at end of file diff --git a/.github/workflows/test-system.yml b/.github/workflows/test-system.yml index b6a827c4d1cc2..be473954039ef 100644 --- a/.github/workflows/test-system.yml +++ b/.github/workflows/test-system.yml @@ -12,7 +12,7 @@ jobs: system-test-debian: timeout-minutes: 10 name: "python on debian" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: debian:trixie-20260421@sha256:35b8ff74ead4880f22090b617372daff0ccae742eb5674455d542bef71ef1999 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -44,7 +44,7 @@ jobs: system-test-fedora: timeout-minutes: 10 name: "python on fedora" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: fedora:45@sha256:af8cdc432037f5e8e288bbc26c2b55b96000a911ec5b37959cd464d830f6cc5b steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -71,7 +71,7 @@ jobs: system-test-ubuntu: timeout-minutes: 10 name: "python3.12 via setup-python" - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -98,7 +98,7 @@ jobs: system-test-python-36: timeout-minutes: 10 name: "python3.6 on debian buster" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: python:3.6-buster steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -122,7 +122,7 @@ jobs: system-test-python-37: timeout-minutes: 10 name: "python3.7 on debian buster" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: python:3.7-buster steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -147,7 +147,7 @@ jobs: # system-test-opensuse: # timeout-minutes: 5 # name: "python on opensuse" - # runs-on: incredibuild-runner + # runs-on: ubuntu-latest # container: opensuse/tumbleweed # steps: # - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -182,7 +182,7 @@ jobs: system-test-rocky-linux: timeout-minutes: 10 name: "python on rocky linux ${{ matrix.rocky-version }}" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: rockylinux/rockylinux:${{ matrix.rocky-version }} strategy: fail-fast: false @@ -241,7 +241,7 @@ jobs: system-test-graalpy: timeout-minutes: 10 name: "graalpy on linux" - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -268,7 +268,7 @@ jobs: system-test-pypy: timeout-minutes: 10 name: "pypy on linux" - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -295,7 +295,7 @@ jobs: system-test-pyston: timeout-minutes: 10 name: "pyston on linux" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: pyston/pyston:2.3.5 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -319,7 +319,7 @@ jobs: system-test-chainguard-dev: timeout-minutes: 10 name: "python on chainguard-dev" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: image: cgr.dev/chainguard/python:latest-dev@sha256:c2ac4118658f7f5a07fcdf31dafb7adca7e7edaf3ad5121585b5f83b79bd85ed options: --user root --entrypoint /bin/sh @@ -348,7 +348,7 @@ jobs: system-test-chainguard: timeout-minutes: 10 name: "python on chainguard" - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -373,7 +373,7 @@ jobs: system-test-alpine: timeout-minutes: 10 name: "python on alpine" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: alpine:latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -651,7 +651,7 @@ jobs: system-test-pyenv: timeout-minutes: 10 name: "python3.9 via pyenv" - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -693,7 +693,7 @@ jobs: system-test-linux-313: timeout-minutes: 10 name: "python3.13 via setup-python" - runs-on: incredibuild-runner + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -731,7 +731,7 @@ jobs: - { os: "linux", target: "linux-libc", - runner: "incredibuild-runner", + runner: "ubuntu-latest", arch: "x86-64", } - { @@ -786,7 +786,7 @@ jobs: system-test-amazonlinux: timeout-minutes: 10 name: "python on amazonlinux" - runs-on: incredibuild-runner + runs-on: ubuntu-latest container: amazonlinux:2023 steps: - name: "Install base requirements" @@ -847,4 +847,4 @@ jobs: run: echo $(which python) - name: "Validate embedded Python install" - run: python ./scripts/check_embedded_python.py --uv ./uv.exe + run: python ./scripts/check_embedded_python.py --uv ./uv.exe \ No newline at end of file diff --git a/.github/workflows/test-windows-trampolines.yml b/.github/workflows/test-windows-trampolines.yml index 65edfa3435de7..cf3ac97374a66 100644 --- a/.github/workflows/test-windows-trampolines.yml +++ b/.github/workflows/test-windows-trampolines.yml @@ -13,7 +13,7 @@ jobs: # Verify windows crate version matches between workspaces windows-version-check: timeout-minutes: 5 - runs-on: incredibuild-runner + runs-on: ubuntu-latest name: "check windows crate version" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -32,7 +32,7 @@ jobs: # disable this job if: false timeout-minutes: 30 - runs-on: incredibuild-runner + runs-on: ubuntu-latest name: "check reproducible build" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -152,4 +152,4 @@ jobs: working-directory: ${{ env.UV_WORKSPACE }} run: | # We turn off the default "production" test feature since these are debug binaries - cargo test -p uv-trampoline-builder --target ${{ matrix.target-arch }}-pc-windows-msvc --no-default-features + cargo test -p uv-trampoline-builder --target ${{ matrix.target-arch }}-pc-windows-msvc --no-default-features \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dc81923580d20..cd085b288cf2a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -322,4 +322,4 @@ jobs: path: pending-snapshots/ if-no-files-found: ignore include-hidden-files: true - retention-days: 14 + retention-days: 14 \ No newline at end of file From 9a06367b4744373cafca680ef8dd17dd9cdc6f25 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 11:30:57 +0300 Subject: [PATCH 23/28] ci: apply prettier --write to workflow YAML The wave-21 sed-based runner relabel left trailing-whitespace style drift that prettier flags. Pure formatting; one line per file. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/bench.yml | 2 +- .github/workflows/build-dev-binaries.yml | 2 +- .github/workflows/build-docker.yml | 2 +- .github/workflows/build-release-binaries.yml | 2 +- .github/workflows/check-docs.yml | 2 +- .github/workflows/check-fmt.yml | 2 +- .github/workflows/check-generated-files.yml | 2 +- .github/workflows/check-lint.yml | 2 +- .github/workflows/check-publish.yml | 2 +- .github/workflows/check-release.yml | 2 +- .github/workflows/check-zizmor.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/probe-incredibuild.yml | 2 +- .github/workflows/publish-crates.yml | 2 +- .github/workflows/publish-docs.yml | 2 +- .github/workflows/publish-mirror.yml | 2 +- .github/workflows/publish-pypi.yml | 2 +- .github/workflows/publish-versions.yml | 2 +- .github/workflows/release-prepare.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/sync-python-releases.yml | 2 +- .github/workflows/test-ecosystem.yml | 2 +- .github/workflows/test-integration.yml | 2 +- .github/workflows/test-smoke.yml | 2 +- .github/workflows/test-system.yml | 2 +- .github/workflows/test-windows-trampolines.yml | 2 +- .github/workflows/test.yml | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 508ed4858b76c..38b494c6116a0 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -137,4 +137,4 @@ jobs: with: run: cargo codspeed run mode: simulation - token: ${{ secrets.CODSPEED_TOKEN }} \ No newline at end of file + token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index 184dddcbdf790..f01d2acdc72b6 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -422,4 +422,4 @@ jobs: run-in-vm: | mv target/x86_64-unknown-freebsd/no-debug/uv uv chmod +x uv - ./uv --version \ No newline at end of file + ./uv --version diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 27b8d7b920cae..4e3fc2a24007f 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -492,4 +492,4 @@ jobs: uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 with: subject-name: ${{ env.UV_GHCR_IMAGE }} - subject-digest: ${{ steps.manifest-digest.outputs.digest }} \ No newline at end of file + subject-digest: ${{ steps.manifest-digest.outputs.digest }} diff --git a/.github/workflows/build-release-binaries.yml b/.github/workflows/build-release-binaries.yml index 749c4b832415b..c3cca9840e2ea 100644 --- a/.github/workflows/build-release-binaries.yml +++ b/.github/workflows/build-release-binaries.yml @@ -1228,4 +1228,4 @@ jobs: path: wheels merge-multiple: true - name: "Check wheel contents" - run: uv run --no-project scripts/check_uv_wheel_contents.py wheels/* \ No newline at end of file + run: uv run --no-project scripts/check_uv_wheel_contents.py wheels/* diff --git a/.github/workflows/check-docs.yml b/.github/workflows/check-docs.yml index 2cd15f126a847..605f2235a9951 100644 --- a/.github/workflows/check-docs.yml +++ b/.github/workflows/check-docs.yml @@ -28,4 +28,4 @@ jobs: cargo dev generate-env-vars-reference - name: "Build docs" - run: uv run --only-group docs mkdocs build --strict -f mkdocs.yml \ No newline at end of file + run: uv run --only-group docs mkdocs build --strict -f mkdocs.yml diff --git a/.github/workflows/check-fmt.yml b/.github/workflows/check-fmt.yml index 22be3a16f345f..90b9dfd5b4d63 100644 --- a/.github/workflows/check-fmt.yml +++ b/.github/workflows/check-fmt.yml @@ -38,4 +38,4 @@ jobs: uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: version: "0.11.8" - - run: uvx ruff format --diff . \ No newline at end of file + - run: uvx ruff format --diff . diff --git a/.github/workflows/check-generated-files.yml b/.github/workflows/check-generated-files.yml index 95261619d2a3f..ae92ca1ca8c75 100644 --- a/.github/workflows/check-generated-files.yml +++ b/.github/workflows/check-generated-files.yml @@ -46,4 +46,4 @@ jobs: run: cargo dev generate-sysconfig-metadata --mode check - name: "Check JSON schema" if: ${{ inputs.schema-changed == 'true' }} - run: cargo dev generate-json-schema --mode check \ No newline at end of file + run: cargo dev generate-json-schema --mode check diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index bd3e8266f5428..afbf5a3096da2 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -170,4 +170,4 @@ jobs: if [ "$(id -u)" = "0" ]; then SUDO=""; else SUDO="sudo"; fi $SUDO apt-get update && $SUDO apt-get install -y wget fi - - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1 \ No newline at end of file + - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1 diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index 1948d3fc57ed6..4f75eeefdae6e 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -22,4 +22,4 @@ jobs: with: save-if: ${{ github.ref == 'refs/heads/main' }} - name: "cargo publish dry-run" - run: ./scripts/cargo-ib.sh publish --workspace --dry-run \ No newline at end of file + run: ./scripts/cargo-ib.sh publish --workspace --dry-run diff --git a/.github/workflows/check-release.yml b/.github/workflows/check-release.yml index e266177ef41f1..3d8944cd2160c 100644 --- a/.github/workflows/check-release.yml +++ b/.github/workflows/check-release.yml @@ -31,4 +31,4 @@ jobs: run: | dist plan --output-format=json > plan-dist-manifest.json echo "dist plan completed successfully" - cat plan-dist-manifest.json \ No newline at end of file + cat plan-dist-manifest.json diff --git a/.github/workflows/check-zizmor.yml b/.github/workflows/check-zizmor.yml index 6122095875fef..eef8fa85737b0 100644 --- a/.github/workflows/check-zizmor.yml +++ b/.github/workflows/check-zizmor.yml @@ -13,4 +13,4 @@ jobs: with: persist-credentials: false - - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 \ No newline at end of file + - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79da2f5a1fb54..40c811a18f408 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -416,4 +416,4 @@ jobs: exit 1 fi env: - NEEDS_JSON: ${{ toJSON(needs) }} \ No newline at end of file + NEEDS_JSON: ${{ toJSON(needs) }} diff --git a/.github/workflows/probe-incredibuild.yml b/.github/workflows/probe-incredibuild.yml index 2284dcaa4f6a1..e3a923330233c 100644 --- a/.github/workflows/probe-incredibuild.yml +++ b/.github/workflows/probe-incredibuild.yml @@ -146,4 +146,4 @@ jobs: run: | ls -la /dev/loop* 2>/dev/null ls -la /dev/kvm 2>/dev/null - ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 \ No newline at end of file + ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml index c323e3640a59e..9c0ad1c155b09 100644 --- a/.github/workflows/publish-crates.yml +++ b/.github/workflows/publish-crates.yml @@ -35,4 +35,4 @@ jobs: # Note `--no-verify` is safe because we do a publish dry-run elsewhere in CI run: cargo +nightly-2026-04-15 publish --workspace --no-verify -Zpublish-timeout --config 'publish.timeout=600' env: - CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} \ No newline at end of file + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 6a9ee509bd893..bbed92921dea5 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -140,4 +140,4 @@ jobs: # auto-merge the PR if the build was triggered by a release. Manual builds should be reviewed by a human. # give the PR a few seconds to be created before trying to auto-merge it sleep 10 - gh pr merge --squash $branch_name \ No newline at end of file + gh pr merge --squash $branch_name diff --git a/.github/workflows/publish-mirror.yml b/.github/workflows/publish-mirror.yml index 32c20293c1aad..b46571687d9ba 100644 --- a/.github/workflows/publish-mirror.yml +++ b/.github/workflows/publish-mirror.yml @@ -57,4 +57,4 @@ jobs: --cache-control "public, max-age=300" \ "artifacts/${installer}" \ "s3://${R2_BUCKET}/installers/uv/latest/${installer}" - done \ No newline at end of file + done diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index d7f50df57315e..85c915e352b32 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -46,4 +46,4 @@ jobs: path: wheels_uv_build merge-multiple: true - name: Publish to PyPI - run: uv publish -v wheels_uv_build/* \ No newline at end of file + run: uv publish -v wheels_uv_build/* diff --git a/.github/workflows/publish-versions.yml b/.github/workflows/publish-versions.yml index 7db08f22d4e17..1e4f51f2a614f 100644 --- a/.github/workflows/publish-versions.yml +++ b/.github/workflows/publish-versions.yml @@ -74,4 +74,4 @@ jobs: run: | # Wait for PR to be created before merging sleep 10 - gh pr merge --squash "$BRANCH_NAME" \ No newline at end of file + gh pr merge --squash "$BRANCH_NAME" diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml index 5ebed23342799..86b54987dec15 100644 --- a/.github/workflows/release-prepare.yml +++ b/.github/workflows/release-prepare.yml @@ -65,4 +65,4 @@ jobs: --head "$branch" \ --fill env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5d2c7eb64af20..c9cb94891866f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -393,4 +393,4 @@ jobs: plan: ${{ needs.plan.outputs.val }} secrets: inherit permissions: - "contents": "read" \ No newline at end of file + "contents": "read" diff --git a/.github/workflows/sync-python-releases.yml b/.github/workflows/sync-python-releases.yml index 635a3700dcc98..d8ae66e719b5e 100644 --- a/.github/workflows/sync-python-releases.yml +++ b/.github/workflows/sync-python-releases.yml @@ -56,4 +56,4 @@ jobs: title: "Sync latest Python releases" body: "Automated update for Python releases." base: "main" - draft: true \ No newline at end of file + draft: true diff --git a/.github/workflows/test-ecosystem.yml b/.github/workflows/test-ecosystem.yml index e6bf3097d665f..e37bfbb53f2fe 100644 --- a/.github/workflows/test-ecosystem.yml +++ b/.github/workflows/test-ecosystem.yml @@ -62,4 +62,4 @@ jobs: else $cmd fi - done \ No newline at end of file + done diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 2f8447edbb51a..c35406623dbd9 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -1170,4 +1170,4 @@ jobs: run: curl -LsSf "https://github.com/astral-sh/uv/releases/latest/download/uv-aarch64-apple-darwin.tar.gz" | tar -xvz - name: "Check cache compatibility" - run: python scripts/check_cache_compat.py --uv-current ./uv --uv-previous ./uv-aarch64-apple-darwin/uv \ No newline at end of file + run: python scripts/check_cache_compat.py --uv-current ./uv --uv-previous ./uv-aarch64-apple-darwin/uv diff --git a/.github/workflows/test-smoke.yml b/.github/workflows/test-smoke.yml index bf825a1c2eaf4..a92e64c4ea0f4 100644 --- a/.github/workflows/test-smoke.yml +++ b/.github/workflows/test-smoke.yml @@ -179,4 +179,4 @@ jobs: - name: "Test uvx shell completions" working-directory: ${{ env.UV_WORKSPACE }} run: | - (& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression \ No newline at end of file + (& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression diff --git a/.github/workflows/test-system.yml b/.github/workflows/test-system.yml index be473954039ef..d0e23a06d447b 100644 --- a/.github/workflows/test-system.yml +++ b/.github/workflows/test-system.yml @@ -847,4 +847,4 @@ jobs: run: echo $(which python) - name: "Validate embedded Python install" - run: python ./scripts/check_embedded_python.py --uv ./uv.exe \ No newline at end of file + run: python ./scripts/check_embedded_python.py --uv ./uv.exe diff --git a/.github/workflows/test-windows-trampolines.yml b/.github/workflows/test-windows-trampolines.yml index cf3ac97374a66..a70c2f6d77787 100644 --- a/.github/workflows/test-windows-trampolines.yml +++ b/.github/workflows/test-windows-trampolines.yml @@ -152,4 +152,4 @@ jobs: working-directory: ${{ env.UV_WORKSPACE }} run: | # We turn off the default "production" test feature since these are debug binaries - cargo test -p uv-trampoline-builder --target ${{ matrix.target-arch }}-pc-windows-msvc --no-default-features \ No newline at end of file + cargo test -p uv-trampoline-builder --target ${{ matrix.target-arch }}-pc-windows-msvc --no-default-features diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cd085b288cf2a..dc81923580d20 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -322,4 +322,4 @@ jobs: path: pending-snapshots/ if-no-files-found: ignore include-hidden-files: true - retention-days: 14 \ No newline at end of file + retention-days: 14 From fa31d307485bdef378d4bc62da818d027ed4aaf4 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 11:33:01 +0300 Subject: [PATCH 24/28] ci: per-job CARGO_HOME + CARGO_TARGET_DIR for all build-dev-binaries Linux jobs Wave-21 refocus exposed concurrent shared-cache corruption: with 5+ build-dev-binaries Linux jobs running in parallel on the IB runner and all writing to /ib-workspace/cache/cargo* via the symlink in cargo-ib.sh, they corrupt each other's incremental cache and .rmeta files (saw rkyv_derive E0786 "invalid metadata files" on linux libc, similar on linux musl). Fix mirrors what we already did for msrv and sdist: pin CARGO_HOME and CARGO_TARGET_DIR to job-local paths so each concurrent job has isolated cargo state. ib_console's build cache (controlled separately by --build-cache-local-shared) still provides cross-job acceleration via content-addressed object caching, independent of CARGO_TARGET_DIR. Applied to: linux-libc, linux-aarch64, linux-armv7-gnueabihf, linux-musl, android-aarch64. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build-dev-binaries.yml | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/workflows/build-dev-binaries.yml b/.github/workflows/build-dev-binaries.yml index f01d2acdc72b6..b4ec694d986cf 100644 --- a/.github/workflows/build-dev-binaries.yml +++ b/.github/workflows/build-dev-binaries.yml @@ -19,6 +19,15 @@ jobs: name: "linux libc" timeout-minutes: 10 runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs and produces "found invalid metadata files" / "unclosed + # delimiter" corruption (rkyv_derive, indexmap, etc.). IB's + # ib_console build cache (separate from CARGO_TARGET_DIR) still + # accelerates compile across runs. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -47,6 +56,15 @@ jobs: name: "linux aarch64" timeout-minutes: 10 runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs and produces "found invalid metadata files" / "unclosed + # delimiter" corruption (rkyv_derive, indexmap, etc.). IB's + # ib_console build cache (separate from CARGO_TARGET_DIR) still + # accelerates compile across runs. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -75,6 +93,15 @@ jobs: name: "linux armv7 gnueabihf" timeout-minutes: 15 runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs and produces "found invalid metadata files" / "unclosed + # delimiter" corruption (rkyv_derive, indexmap, etc.). IB's + # ib_console build cache (separate from CARGO_TARGET_DIR) still + # accelerates compile across runs. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -114,6 +141,15 @@ jobs: name: "linux musl" timeout-minutes: 10 runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs and produces "found invalid metadata files" / "unclosed + # delimiter" corruption (rkyv_derive, indexmap, etc.). IB's + # ib_console build cache (separate from CARGO_TARGET_DIR) still + # accelerates compile across runs. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -310,6 +346,15 @@ jobs: name: "android aarch64" timeout-minutes: 15 runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs and produces "found invalid metadata files" / "unclosed + # delimiter" corruption (rkyv_derive, indexmap, etc.). IB's + # ib_console build cache (separate from CARGO_TARGET_DIR) still + # accelerates compile across runs. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From 19bdbb7cc695d2b0a4c0c25402642252b2cc90ba Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 11:45:31 +0300 Subject: [PATCH 25/28] ci: unwrap cargo publish --dry-run from ib_console (same exit-101 pattern as nextest) --- .github/workflows/check-publish.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index 4f75eeefdae6e..295632b96ec89 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -22,4 +22,9 @@ jobs: with: save-if: ${{ github.ref == 'refs/heads/main' }} - name: "cargo publish dry-run" - run: ./scripts/cargo-ib.sh publish --workspace --dry-run + # Plain cargo here — ib_console crashes mid-run on this + # workspace-wide dry-run with the same exit-101 pattern we + # see on cargo nextest run; appears to be ib_console's limit + # for sustained workspace-scale compilation under + # --build-cache-force. Unwrapping until IB resolves. + run: cargo publish --workspace --dry-run From de9799f220e9c803982a6db24b8fe0aea3cba06f Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 11:53:44 +0300 Subject: [PATCH 26/28] ci: isolate CARGO_HOME on all remaining IB cargo jobs Wave-23 confirmed the same /ib-workspace/cache/cargo/registry/ shared-cache corruption that hit linux libc/musl in wave 21 also hits clippy-ubuntu (NUL bytes in indexmap source). Apply the same per-job CARGO_HOME + CARGO_TARGET_DIR isolation we already use on sdist/msrv/build-dev-binaries to: - bench/{walltime-build, simulated} - check-generated-files/cargo-dev-generate-all (was missing CARGO_HOME) - check-lint/clippy-ubuntu - test/cargo-test-linux Every IB-runner cargo job is now isolated. ib_console build cache (separate from CARGO_TARGET_DIR) still provides cross-job acceleration via content-addressed object caching. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/bench.yml | 16 ++++++++++++++++ .github/workflows/check-generated-files.yml | 1 + .github/workflows/check-lint.yml | 8 ++++++++ .github/workflows/test.yml | 8 ++++++++ 4 files changed, 33 insertions(+) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 38b494c6116a0..092afac4f6179 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -23,6 +23,14 @@ jobs: name: "walltime build" # codspeed-macro doesn't support Ubuntu 24.04 yet runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs, leading to NUL-byte source corruption (indexmap, + # rkyv_derive) under workspace-scale compilation. ib_console + # build cache (separate) still accelerates compile. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target if: ${{ github.repository == 'astral-sh/uv' }} timeout-minutes: 20 steps: @@ -101,6 +109,14 @@ jobs: benchmarks-simulated: name: "simulated" runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs, leading to NUL-byte source corruption (indexmap, + # rkyv_derive) under workspace-scale compilation. ib_console + # build cache (separate) still accelerates compile. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target if: ${{ github.repository == 'astral-sh/uv' }} timeout-minutes: 20 steps: diff --git a/.github/workflows/check-generated-files.yml b/.github/workflows/check-generated-files.yml index ae92ca1ca8c75..b873721b39848 100644 --- a/.github/workflows/check-generated-files.yml +++ b/.github/workflows/check-generated-files.yml @@ -29,6 +29,7 @@ jobs: # stale-rlib linker errors here ("undefined symbol …which…"). # Per-job target dir avoids the race; we sacrifice some cache # reuse for correctness on this fast-running job. + CARGO_HOME: ${{ github.workspace }}/.cargo CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index afbf5a3096da2..517fb216fd2fc 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -96,6 +96,14 @@ jobs: timeout-minutes: 10 if: ${{ inputs.code-changed == 'true' || github.ref == 'refs/heads/main' }} runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs, leading to NUL-byte source corruption (indexmap, + # rkyv_derive) under workspace-scale compilation. ib_console + # build cache (separate) still accelerates compile. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dc81923580d20..a04f97ec757e5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,6 +27,14 @@ jobs: cargo-test-linux: timeout-minutes: 10 runs-on: incredibuild-runner + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs, leading to NUL-byte source corruption (indexmap, + # rkyv_derive) under workspace-scale compilation. ib_console + # build cache (separate) still accelerates compile. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target name: "cargo test on linux" steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 From 16f3d6816d84d71d51c344171663cbc89c1d3404 Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 12:15:01 +0300 Subject: [PATCH 27/28] ci: isolate CARGO_HOME for check-publish too (was missing wave-24 sweep) --- .github/workflows/check-publish.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index 295632b96ec89..25b3707b09099 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -14,6 +14,14 @@ jobs: timeout-minutes: 20 runs-on: incredibuild-runner name: "cargo publish dry-run" + env: + # Per-job CARGO_HOME / CARGO_TARGET_DIR. Without this the IB + # runner shares /ib-workspace/cache/cargo* across concurrent + # jobs, leading to NUL-byte source corruption (indexmap, + # rkyv_derive). ib_console build cache (separate) still + # accelerates compile. + CARGO_HOME: ${{ github.workspace }}/.cargo + CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From 25dbe9da8c833f5563e0dad995242218d551199a Mon Sep 17 00:00:00 2001 From: Yossi Eliaz Date: Sun, 10 May 2026 14:15:46 +0300 Subject: [PATCH 28/28] chore: remove diagnostic scaffolding before merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Delete .github/workflows/probe-incredibuild.yml (diagnostic workflow was useful for validating IB image inventory side-by-side vs ubuntu-latest; not part of the production CI architecture). - Revert the uv-version source comment from wave 18; it didn't actually unblock the bench gating (run-bench output stays false for unrelated plan-step reasons), so it's dead noise. PR is now scoped to the workflow + helper-script changes that deliver the measured −33% median CI speedup. No source code changes; all work isolated to .github/workflows/ and scripts/. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/probe-incredibuild.yml | 149 ----------------------- crates/uv-version/src/lib.rs | 6 - 2 files changed, 155 deletions(-) delete mode 100644 .github/workflows/probe-incredibuild.yml diff --git a/.github/workflows/probe-incredibuild.yml b/.github/workflows/probe-incredibuild.yml deleted file mode 100644 index e3a923330233c..0000000000000 --- a/.github/workflows/probe-incredibuild.yml +++ /dev/null @@ -1,149 +0,0 @@ -name: probe-incredibuild -# Diagnostic-only workflow. Runs both on incredibuild-runner and on -# ubuntu-latest and prints exhaustive environment + tool inventory so -# we can pinpoint exactly where Incredibuild's runner image differs -# from a stock GitHub-hosted Linux runner. Triggered manually only. - -on: - workflow_dispatch: - # Also trigger on changes to this file so we can iterate without - # needing the workflow to live on the default branch (GitHub's - # workflow_dispatch only registers workflows from default branch). - push: - paths: - - .github/workflows/probe-incredibuild.yml - -permissions: {} - -jobs: - probe-ib: - name: "probe on incredibuild-runner" - runs-on: incredibuild-runner - timeout-minutes: 10 - steps: - - name: "Identity" - run: | - echo "=== whoami / id ===" - id; whoami - echo "=== uname ===" - uname -a - echo "=== /etc/os-release ===" - cat /etc/os-release || true - echo "=== cgroup ===" - cat /proc/1/cgroup 2>/dev/null | head -5 || true - echo "=== runner env ===" - env | grep -iE "^(RUNNER_|GITHUB_|IB_|INCREDIBUILD_)" | sort - - - name: "PATH and ib-accel interception" - run: | - echo "=== PATH ===" - echo "$PATH" | tr ':' '\n' - echo "=== ib-accel binaries ===" - ls -la /ib-workspace/incredibuild/ib-accel/bin 2>/dev/null || echo "(ib-accel/bin not present)" - echo "=== which docker (which one wins) ===" - which -a docker || true - ls -la "$(which docker)" 2>/dev/null || true - - - name: "Tool inventory (presence + version)" - run: | - for tool in bash zsh sh git curl wget unzip jq sudo apt-get \ - docker buildx qemu-system-aarch64 binfmt-support \ - node npm npx python3 python pip rustup cargo rustc clippy \ - cmake make gcc g++ ld ld.lld gold mold \ - tar gzip xz unrar zip 7z openssl gpg \ - ssh systemctl losetup; do - if command -v "$tool" >/dev/null 2>&1; then - v=$(timeout 3 "$tool" --version 2>&1 | head -1 || echo "(no --version)") - printf " ✅ %-22s %s\n" "$tool" "$v" - else - printf " ❌ %-22s MISSING\n" "$tool" - fi - done - - - name: "Kernel features" - run: | - echo "=== /dev/loop* ===" - ls -la /dev/loop* 2>/dev/null || echo "(no loop devices)" - echo "=== /dev/kvm ===" - ls -la /dev/kvm 2>/dev/null || echo "(no kvm)" - echo "=== binfmt_misc ===" - ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 || echo "(no binfmt_misc)" - echo "=== capabilities ===" - grep -i cap /proc/self/status | head -5 || true - echo "=== /proc/self/uid_map ===" - cat /proc/self/uid_map 2>/dev/null || true - - - name: "Docker probe (this is where ib-accel intercepts)" - run: | - if ! command -v docker >/dev/null 2>&1; then - echo "(no docker binary)" - exit 0 - fi - echo "=== docker version ===" - docker version 2>&1 | head -30 || true - echo - echo "=== docker info ===" - docker info 2>&1 | head -40 || true - echo - echo "=== docker buildx version ===" - docker buildx version 2>&1 || echo "(no buildx)" - echo - echo "=== try: docker run --rm hello-world ===" - docker run --rm hello-world 2>&1 | tail -20 || echo "(hello-world failed: $?)" - echo - echo "=== try: docker buildx ls ===" - docker buildx ls 2>&1 || echo "(buildx ls failed)" - - - name: "ib-accel direct invocation" - run: | - if [ -x /ib-workspace/incredibuild/ib-accel/bin/docker ]; then - echo "=== ib-accel docker --version ===" - /ib-workspace/incredibuild/ib-accel/bin/docker --version 2>&1 || true - echo "=== ib-accel docker info ===" - /ib-workspace/incredibuild/ib-accel/bin/docker info 2>&1 | head -30 || true - else - echo "(no ib-accel docker wrapper)" - fi - - - name: "Cargo cache layout" - run: | - echo "=== /ib-workspace ===" - ls -la /ib-workspace 2>/dev/null || echo "(no /ib-workspace)" - echo "=== /ib-workspace/cache ===" - ls -la /ib-workspace/cache 2>/dev/null || true - echo "=== /ib-workspace/cache/cargo-target (size) ===" - du -sh /ib-workspace/cache/cargo-target 2>/dev/null || true - echo "=== \$CARGO_HOME / \$CARGO_TARGET_DIR ===" - echo "CARGO_HOME=${CARGO_HOME:-(unset)}" - echo "CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-(unset)}" - - probe-gh: - name: "probe on ubuntu-latest (control)" - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: "Same identity probe" - run: | - id; whoami; uname -a - - name: "Tool inventory (presence)" - run: | - for tool in bash node npm npx python3 rustup cargo \ - docker buildx qemu-system-aarch64 \ - curl wget unzip jq sudo losetup; do - if command -v "$tool" >/dev/null 2>&1; then - v=$(timeout 3 "$tool" --version 2>&1 | head -1) - printf " ✅ %-22s %s\n" "$tool" "$v" - else - printf " ❌ %-22s MISSING\n" "$tool" - fi - done - - name: "Docker probe" - run: | - docker version 2>&1 | head -30 - docker buildx version - docker run --rm hello-world 2>&1 | tail -20 - - name: "Kernel features" - run: | - ls -la /dev/loop* 2>/dev/null - ls -la /dev/kvm 2>/dev/null - ls /proc/sys/fs/binfmt_misc/ 2>/dev/null | head -10 diff --git a/crates/uv-version/src/lib.rs b/crates/uv-version/src/lib.rs index e309fe63be705..20a8940a12164 100644 --- a/crates/uv-version/src/lib.rs +++ b/crates/uv-version/src/lib.rs @@ -1,12 +1,6 @@ /// Return the application version. /// /// This should be in sync with uv's version based on the Crate version. -// -// CI note: this file is intentionally touched on the -// Incredibuild-RND/uv fork to flip `any_rust_changed=1` in the CI -// plan step, which unblocks the bench workflow so we can validate -// ib_console acceleration on cargo-run benchmarks. Safe to drop on -// the next upstream sync. pub fn version() -> &'static str { env!("CARGO_PKG_VERSION") }