From f4afd95cbc1e597c8bc5511b6f6c7847bb1bfd57 Mon Sep 17 00:00:00 2001 From: Mike Evdokimov Date: Fri, 12 Jun 2026 19:02:09 +0600 Subject: [PATCH] Add FAQ section on caching cibuildwheel's downloaded tools (#2842) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add FAQ section on caching cibuildwheel's downloaded tools Adds a Tips entry covering: - What cibuildwheel caches (CPython/PyPy installers, virtualenv, python-build-standalone archives) and the default per-OS cache folder. - How to override the cache location with ``CIBW_CACHE_PATH``. - A worked GitHub Actions example pairing ``actions/cache`` with ``CIBW_CACHE_PATH`` so the cache survives between runs. - A pointer to ``--clean-cache`` for invalidating stale entries. Closes #1585. Per @joerick's request in the issue ("a caching section in the FAQ would be great, if you can contribute it") the scope is intentionally narrow — just FAQ-level guidance. Platform-specific caching (e.g. Windows NuGet, addressed in #2839) lives in the platforms doc. * docs: bump actions/cache v4 to v5 * docs: move cache to runner.temp, add cache poisoning warning (review feedback) --- docs/faq.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/faq.md b/docs/faq.md index 456022a4..30809490 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -102,6 +102,51 @@ Meson generally works well with cibuildwheel, but there are a few things to be a - If you need to build 32-bit Windows wheels, you need to activate a 32-bit compiler toolchain before starting cibuildwheel. Many users use [ilammy/msvc-dev-cmd](https://github.com/ilammy/msvc-dev-cmd) for this purpose. +### Caching cibuildwheel's downloaded tools {: #caching} + +To speed up builds, cibuildwheel caches the tools it downloads — CPython/PyPy installers, [`virtualenv`][virtualenv], [python-build-standalone][pbs] archives used on Android/iOS, etc. The active cache folder is printed in the preamble of every run: + +``` +Cache folder: /Users/Matt/Library/Caches/cibuildwheel +``` + +By default it lives under the OS user-cache directory: + +| Platform | Default cache folder | +| ------------ | --------------------------------------------- | +| Linux | `~/.cache/cibuildwheel` | +| macOS / iOS | `~/Library/Caches/cibuildwheel` | +| Windows | `%LOCALAPPDATA%\pypa\cibuildwheel\Cache` | + +Set the `CIBW_CACHE_PATH` environment variable to point cibuildwheel at a different folder. On CI you'll typically want a workflow-defined path so that the runner's cache action can persist it between runs. + +#### Persisting the cache on GitHub Actions + +```yaml +- uses: actions/cache@v5 + with: + path: ${{ runner.temp }}/cibw-cache + key: cibw-${{ runner.os }}-${{ hashFiles('pyproject.toml') }} + restore-keys: | + cibw-${{ runner.os }}- + +- uses: pypa/cibuildwheel@v3.4.1 + env: + CIBW_CACHE_PATH: ${{ runner.temp }}/cibw-cache +``` + +The `restore-keys` fallback lets a slightly stale cache still be reused if `pyproject.toml` changes. Adjust the cache key to whatever set of inputs determines what cibuildwheel will download (e.g. include a hash of `pyproject.toml`'s `[tool.cibuildwheel]` section, or pin on a Python build-tools version). + +For platform-specific notes (e.g. caching the official python.org installers on macOS, or NuGet CPython downloads on Windows), see the [platforms documentation](platforms.md). + +If the cache becomes stale or corrupt, run `cibuildwheel --clean-cache` (or simply delete the folder) before re-running. + +!!! warning "Cache poisoning security risk" + Use of caching in a release pipeline means the cache folder is now a possible security risk - an attacker could [poison the cache](https://hivesecurity.gitlab.io/blog/github-actions-cache-poisoning-supply-chain/) with executables they have compromised. If you use this for release builds, consider who has access to modify the cache. Specifically be careful if your repo has any workflows using `pull_request_target`, even if they appear unrelated. + +[virtualenv]: https://virtualenv.pypa.io/ +[pbs]: https://gregoryszorc.com/docs/python-build-standalone/main/ + ### Automatic updates using Dependabot {: #automatic-updates} Selecting a moving target (like the latest release) is generally a bad idea in CI. If something breaks, you can't tell whether it was your code or an upstream update that caused the breakage, and in a worst-case scenario, it could occur during a release.