* feat: Add `mirror` and `mirror-token` inputs for custom Python distribution sources
Users who need custom CPython builds (internal mirrors, GHES-hosted forks,
special build configurations, compliance builds, air-gapped runners) could not
previously point setup-python at anything other than actions/python-versions.
Adds two new inputs:
- `mirror`: base URL hosting versions-manifest.json and the Python
distributions it references. Defaults to the existing
https://raw.githubusercontent.com/actions/python-versions/main.
- `mirror-token`: optional token used to authenticate requests to the mirror.
If `mirror` is a raw.githubusercontent.com/{owner}/{repo}/{branch} URL, the
manifest is fetched via the GitHub REST API (authenticated rate limit applies);
otherwise the action falls back to a direct GET of {mirror}/versions-manifest.json.
Token interaction
-----------------
`token` is never forwarded to arbitrary hosts. Auth resolution is per-URL:
1. if mirror-token is set, use mirror-token
2. else if token is set AND the target host is github.com,
*.github.com, or *.githubusercontent.com, use token
3. else send no auth
Cases:
Default (no inputs set)
mirror = default raw.githubusercontent.com URL, mirror-token empty,
token = github.token.
→ manifest API call and tarball downloads use `token`.
Identical to prior behavior.
Custom raw.githubusercontent.com mirror (e.g. personal fork)
mirror-token empty, token = github.token.
→ manifest API call and tarball downloads use `token`
(target hosts are GitHub-owned).
Custom non-GitHub mirror, no mirror-token
mirror-token empty, token = github.token.
→ manifest fetched via direct URL (no auth attached),
tarball downloads use no auth.
`token` is NOT forwarded to the custom host — this is the
leak-prevention case.
Custom non-GitHub mirror with mirror-token
mirror-token set, token may be set.
→ manifest fetch and tarball downloads use `mirror-token`.
Custom GitHub mirror with both tokens set
mirror-token wins. Used for both the manifest API call and
tarball downloads.
* fix: address mirror review feedback
- scope mirror-token to the mirror host and send it verbatim
- route non-repo mirrors straight to the URL fetch instead of throwing
- authenticate the manifest fetch
- warn on slash branches, and on mirror with PyPy/GraalPy
- memoize mirror validation
- exercise the direct-URL path in the E2E job
Addresses https://github.com/actions/setup-python/pull/1302#issuecomment-5202618946
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix: correct mirror warnings, auth scoping, and integration coverage
- only warn about PyPy/GraalPy mirror when a custom mirror is set; the
action.yml default made the warning fire on every run
- accept the refs/heads/{branch} raw URL form so it routes via the REST
API instead of tripping the slash-branch warning
- scope mirror-token to the full mirror origin (scheme+host+port) so it
can't leak to a same-host http download_url
- make an invalid mirror fatal on the auth path, matching getManifestUrl
- fix warning/docs that wrongly claimed the raw fallback is anonymous
- force a manifest fetch in the mirror integration job (check-latest) so
it actually contacts the mirror instead of using the preinstalled cache
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
- Upgrade fast-xml-parser to 5.10.1 (fixes GHSA-8r6m-32jq-jx6q)
- Add package.json override to force brace-expansion >=5.0.8 across
all transitive dependencies (fixes GHSA-mh99-v99m-4gvg) without
downgrading jest/ts-jest
- Refresh .licenses/npm cache to match updated dependency tree
- Rebuild dist/setup and dist/cache-save
npm audit now reports 0 vulnerabilities. Pre-existing test suite
failures (7 suites, ESM/jest teardown issue) verified unrelated to
this change - identical on unmodified main with node 24.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add RHEL support for manifest matching and OS detection
* update dist
* make cache keys distro-aware and key RHEL by major version
* Normalize RHEL OS detection and improve cache key consistency
* Refactor OS info retrieval to use getOSInfo and handle null cases for improved reliability
* logic to update install oath with --user flg
* format update
* format update
* update
* test job to validate --user flag installtion
* updated the script
* updated the yaml
* update the inputs
* updated script
* update the correct script file name
* updated script and yaml
* npm run format-check
* fix-test failures
* path update
* check failure fix
* updated test
* update free threaded version
* updated the comments
* Enhance reading from .python-version
* Fix typos
* Fix lint
* Add built files
* Don't use EOL versions in `utils.test.ts`
* Fix Prettier
* Don't use unreleased versions in `utils.test.ts`
* Update versions in `utils.test.ts` again
* include freethread e2e testing and upgrade cache from 4.0.0 to 4.0.2
* include verify gil step and validated python version
* Rename files
* include ubuntu-arm runners for testing
* Support free threaded Python versions like '3.13t'
Python wheels, pyenv, and a number of other tools use 't' in the Python
version number to identify free threaded builds. For example, '3.13t',
'3.14.0a1', '3.14t-dev'.
This PR supports that syntax in `actions/setup-python`, strips the "t",
and adds "-freethreading" to the architecture to select the correct
Python version.
See #771
* Add free threading to advanced usage documentation
* Fix desugaring of `3.13.1t` and add test case.
* Add freethreaded input and fix handling of prerelease versions
* Fix lint
* Add 't' suffix to python-version output
* Use distinct cache key for free threaded Python
* Remove support for syntax like '3.14.0a1'
* Clarify use of 't' suffix
* Improve error message when trying to use free threaded Python versions before 3.13