Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
86f926adf6 Bump smol-toml from 1.4.2 to 1.5.2
Bumps [smol-toml](https://github.com/squirrelchat/smol-toml) from 1.4.2 to 1.5.2.
- [Release notes](https://github.com/squirrelchat/smol-toml/releases)
- [Commits](https://github.com/squirrelchat/smol-toml/compare/v1.4.2...v1.5.2)

---
updated-dependencies:
- dependency-name: smol-toml
  dependency-version: 1.5.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-08 10:17:57 +00:00
32 changed files with 14379 additions and 3202 deletions

View File

@@ -23,7 +23,7 @@ and configures the environment for subsequent workflow steps.
**Size**: Small-medium repository (~50 source files, ~400 total files including dependencies) **Size**: Small-medium repository (~50 source files, ~400 total files including dependencies)
**Languages**: TypeScript (primary), JavaScript (compiled output), JSON (configuration) **Languages**: TypeScript (primary), JavaScript (compiled output), JSON (configuration)
**Runtime**: Node.js 24 (GitHub Actions runtime) **Runtime**: Node.js 24 (GitHub Actions runtime)
**Key Dependencies**: @actions/core, @actions/cache, @actions/tool-cache **Key Dependencies**: @actions/core, @actions/cache, @actions/tool-cache, @octokit/core
### Core Architecture ### Core Architecture

View File

@@ -41,13 +41,13 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 uses: github/codeql-action/init@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
source-root: src source-root: src
@@ -59,7 +59,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 uses: github/codeql-action/autobuild@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@@ -73,4 +73,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 uses: github/codeql-action/analyze@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6

View File

@@ -21,14 +21,14 @@ jobs:
permissions: permissions:
security-events: write # for zizmor security-events: write # for zizmor
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Actionlint - name: Actionlint
uses: eifinger/actionlint-action@213860089b7cf97d640aa67567898fabeb132746 # v1.9.3 uses: eifinger/actionlint-action@213860089b7cf97d640aa67567898fabeb132746 # v1.9.3
- name: Run zizmor - name: Run zizmor
uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0 uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with: with:
node-version-file: .nvmrc node-version-file: .nvmrc
cache: npm cache: npm
@@ -51,7 +51,7 @@ jobs:
matrix: matrix:
os: [ubuntu-latest, macos-latest, macos-14, windows-latest] os: [ubuntu-latest, macos-latest, macos-14, windows-latest]
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install latest version - name: Install latest version
@@ -76,7 +76,7 @@ jobs:
test-uv-no-modify-path: test-uv-no-modify-path:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install with UV_NO_MODIFY_PATH set - name: Install with UV_NO_MODIFY_PATH set
@@ -125,7 +125,7 @@ jobs:
expected-version: "0.1.0" expected-version: "0.1.0"
resolution-strategy: "lowest" resolution-strategy: "lowest"
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install version ${{ matrix.input.version-input }} with strategy ${{ matrix.input.resolution-strategy || 'highest' }} - name: Install version ${{ matrix.input.version-input }} with strategy ${{ matrix.input.resolution-strategy || 'highest' }}
@@ -154,7 +154,7 @@ jobs:
matrix: matrix:
version-input: ["latest", ">=0.8"] version-input: ["latest", ">=0.8"]
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install version ${{ matrix.version-input }} - name: Install version ${{ matrix.version-input }}
@@ -182,7 +182,7 @@ jobs:
- working-directory: "__tests__/fixtures/uv-toml-project" - working-directory: "__tests__/fixtures/uv-toml-project"
expected-version: "0.5.15" expected-version: "0.5.15"
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install version from ${{ matrix.input.working-directory }} - name: Install version from ${{ matrix.input.working-directory }}
@@ -208,7 +208,7 @@ jobs:
- version-file: "__tests__/fixtures/.tool-versions" - version-file: "__tests__/fixtures/.tool-versions"
expected-version: "0.5.15" expected-version: "0.5.15"
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install version from ${{ matrix.input.version-file }} - name: Install version from ${{ matrix.input.version-file }}
@@ -225,7 +225,7 @@ jobs:
test-malformed-pyproject-file-fallback: test-malformed-pyproject-file-fallback:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install using malformed pyproject.toml - name: Install using malformed pyproject.toml
@@ -245,7 +245,7 @@ jobs:
- os: macos-latest - os: macos-latest
checksum: "a70cbfbf3bb5c08b2f84963b4f12c94e08fbb2468ba418a3bfe1066fbe9e7218" checksum: "a70cbfbf3bb5c08b2f84963b4f12c94e08fbb2468ba418a3bfe1066fbe9e7218"
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Checksum matches expected - name: Checksum matches expected
@@ -259,7 +259,7 @@ jobs:
test-with-explicit-token: test-with-explicit-token:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install default version - name: Install default version
@@ -272,7 +272,7 @@ jobs:
test-uvx: test-uvx:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install default version - name: Install default version
@@ -285,7 +285,7 @@ jobs:
matrix: matrix:
os: [ubuntu-latest, macos-latest, macos-14, windows-latest] os: [ubuntu-latest, macos-latest, macos-14, windows-latest]
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install default version - name: Install default version
@@ -296,7 +296,7 @@ jobs:
test-tilde-expansion-tool-dirs: test-tilde-expansion-tool-dirs:
runs-on: selfhosted-ubuntu-arm64 runs-on: selfhosted-ubuntu-arm64
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -321,11 +321,10 @@ jobs:
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install latest version - name: Install latest version
id: setup-uv
uses: ./ uses: ./
with: with:
python-version: 3.13.1t python-version: 3.13.1t
@@ -336,14 +335,6 @@ jobs:
exit 1 exit 1
fi fi
shell: bash shell: bash
- name: Verify output python-version is correct
run: |
if [ "$PYTHON_VERSION" != "3.13.1t" ]; then
exit 1
fi
shell: bash
env:
PYTHON_VERSION: ${{ steps.setup-uv.outputs.python-version }}
- run: uv sync - run: uv sync
working-directory: __tests__/fixtures/uv-project working-directory: __tests__/fixtures/uv-project
@@ -353,7 +344,7 @@ jobs:
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install latest version - name: Install latest version
@@ -390,64 +381,14 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: alpine container: alpine
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install latest version - name: Install latest version
id: setup-uv
uses: ./ uses: ./
with:
enable-cache: true
- name: Verify cache key contains alpine
run: |
echo "Cache key: $CACHE_KEY"
if echo "$CACHE_KEY" | grep -qv "alpine"; then
echo "Cache key does not contain 'alpine'"
exit 1
fi
shell: sh
env:
CACHE_KEY: ${{ steps.setup-uv.outputs.cache-key }}
- run: uv sync - run: uv sync
working-directory: __tests__/fixtures/uv-project working-directory: __tests__/fixtures/uv-project
test-cache-key-os-version:
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-22.04
expected-os: "ubuntu-22.04"
- os: ubuntu-24.04
expected-os: "ubuntu-24.04"
- os: macos-14
expected-os: "macos-14"
- os: macos-15
expected-os: "macos-15"
- os: windows-2022
expected-os: "windows-2022"
- os: windows-2025
expected-os: "windows-2025"
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Setup uv
id: setup-uv
uses: ./
with:
enable-cache: true
- name: Verify cache key contains OS version
run: |
echo "Cache key: $CACHE_KEY"
if [[ "$CACHE_KEY" != *"${{ matrix.expected-os }}"* ]]; then
echo "Cache key does not contain expected OS version: ${{ matrix.expected-os }}"
exit 1
fi
shell: bash
env:
CACHE_KEY: ${{ steps.setup-uv.outputs.cache-key }}
test-setup-cache: test-setup-cache:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
@@ -455,7 +396,7 @@ jobs:
enable-cache: ["true", "false", "auto"] enable-cache: ["true", "false", "auto"]
os: ["ubuntu-latest", "selfhosted-ubuntu-arm64", "windows-latest"] os: ["ubuntu-latest", "selfhosted-ubuntu-arm64", "windows-latest"]
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -474,7 +415,7 @@ jobs:
os: ["ubuntu-latest", "selfhosted-ubuntu-arm64", "windows-latest"] os: ["ubuntu-latest", "selfhosted-ubuntu-arm64", "windows-latest"]
needs: test-setup-cache needs: test-setup-cache
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Restore with cache - name: Restore with cache
@@ -508,7 +449,7 @@ jobs:
test-setup-cache-requirements-txt: test-setup-cache-requirements-txt:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -524,7 +465,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: test-setup-cache-requirements-txt needs: test-setup-cache-requirements-txt
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Restore with cache - name: Restore with cache
@@ -548,7 +489,7 @@ jobs:
test-setup-cache-dependency-glob: test-setup-cache-dependency-glob:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -565,7 +506,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: test-setup-cache-dependency-glob needs: test-setup-cache-dependency-glob
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Change pyproject.toml - name: Change pyproject.toml
@@ -593,7 +534,7 @@ jobs:
test-setup-cache-save-cache-false: test-setup-cache-save-cache-false:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -609,7 +550,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: test-setup-cache-save-cache-false needs: test-setup-cache-save-cache-false
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Restore with cache - name: Restore with cache
@@ -629,7 +570,7 @@ jobs:
test-setup-cache-restore-cache-false: test-setup-cache-restore-cache-false:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -644,7 +585,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: test-setup-cache-restore-cache-false needs: test-setup-cache-restore-cache-false
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Restore with cache - name: Restore with cache
@@ -674,7 +615,7 @@ jobs:
expected-cache-dir: "/home/ubuntu/.cache/uv" expected-cache-dir: "/home/ubuntu/.cache/uv"
runs-on: ${{ matrix.inputs.os }} runs-on: ${{ matrix.inputs.os }}
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -692,7 +633,7 @@ jobs:
test-cache-local-cache-disabled: test-cache-local-cache-disabled:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup without cache - name: Setup without cache
@@ -711,7 +652,7 @@ jobs:
test-cache-local-cache-disabled-but-explicit-path: test-cache-local-cache-disabled-but-explicit-path:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup without cache - name: Setup without cache
@@ -731,7 +672,7 @@ jobs:
test-setup-cache-local: test-setup-cache-local:
runs-on: selfhosted-ubuntu-arm64 runs-on: selfhosted-ubuntu-arm64
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup with cache - name: Setup with cache
@@ -746,7 +687,7 @@ jobs:
runs-on: selfhosted-ubuntu-arm64 runs-on: selfhosted-ubuntu-arm64
needs: test-setup-cache-local needs: test-setup-cache-local
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Restore with cache - name: Restore with cache
@@ -769,7 +710,7 @@ jobs:
test-tilde-expansion-cache-local-path: test-tilde-expansion-cache-local-path:
runs-on: selfhosted-ubuntu-arm64 runs-on: selfhosted-ubuntu-arm64
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Create cache directory - name: Create cache directory
@@ -785,7 +726,7 @@ jobs:
test-tilde-expansion-cache-dependency-glob: test-tilde-expansion-cache-dependency-glob:
runs-on: selfhosted-ubuntu-arm64 runs-on: selfhosted-ubuntu-arm64
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Create cache directory - name: Create cache directory
@@ -820,7 +761,7 @@ jobs:
test-no-python-version: test-no-python-version:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Fake pyproject.toml at root - name: Fake pyproject.toml at root
@@ -835,7 +776,7 @@ jobs:
test-custom-manifest-file: test-custom-manifest-file:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install from custom manifest file - name: Install from custom manifest file
@@ -854,7 +795,7 @@ jobs:
test-absolute-path: test-absolute-path:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Create requirements.txt - name: Create requirements.txt
@@ -874,7 +815,7 @@ jobs:
test-relative-path: test-relative-path:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: mkdir - name: mkdir
@@ -898,7 +839,7 @@ jobs:
test-cache-prune-force: test-cache-prune-force:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup uv - name: Setup uv
@@ -915,7 +856,7 @@ jobs:
test-cache-dir-from-file: test-cache-dir-from-file:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Verify uv cache dir is not populated - name: Verify uv cache dir is not populated
@@ -940,7 +881,7 @@ jobs:
test-cache-python-installs: test-cache-python-installs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Verify Python install dir is not populated - name: Verify Python install dir is not populated
@@ -967,7 +908,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: test-cache-python-installs needs: test-cache-python-installs
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Verify Python install dir does not exist - name: Verify Python install dir does not exist
@@ -995,7 +936,7 @@ jobs:
exit 1 exit 1
fi fi
env: env:
CACHE_HIT: ${{ steps.restore.outputs.python-cache-hit }} CACHE_HIT: ${{ steps.restore.outputs.cache-hit }}
- run: uv sync --managed-python - run: uv sync --managed-python
working-directory: __tests__/fixtures/uv-project working-directory: __tests__/fixtures/uv-project
@@ -1011,7 +952,7 @@ jobs:
expected-python-dir: "/home/ubuntu/.local/share/uv/python" expected-python-dir: "/home/ubuntu/.local/share/uv/python"
runs-on: ${{ matrix.inputs.os }} runs-on: ${{ matrix.inputs.os }}
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install latest version - name: Install latest version
@@ -1030,7 +971,7 @@ jobs:
test-act: test-act:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install act - name: Install act
@@ -1042,15 +983,6 @@ jobs:
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
validate-typings:
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Validate typings
uses: typesafegithub/github-actions-typing@184d97003b1300f6a10e286eb98c191e416ff02b # v2.2.1
all-tests-passed: all-tests-passed:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
@@ -1070,7 +1002,6 @@ jobs:
- test-python-version - test-python-version
- test-activate-environment - test-activate-environment
- test-musl - test-musl
- test-cache-key-os-version
- test-cache-local - test-cache-local
- test-cache-local-cache-disabled - test-cache-local-cache-disabled
- test-cache-local-cache-disabled-but-explicit-path - test-cache-local-cache-disabled-but-explicit-path
@@ -1099,7 +1030,6 @@ jobs:
- test-restore-python-installs - test-restore-python-installs
- test-python-install-dir - test-python-install-dir
- test-act - test-act
- validate-typings
if: always() if: always()
steps: steps:
- name: All tests passed - name: All tests passed

View File

@@ -15,10 +15,10 @@ jobs:
contents: write contents: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: true persist-credentials: true
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with: with:
node-version: "20" node-version: "20"
- name: Update known versions - name: Update known versions
@@ -27,6 +27,7 @@ jobs:
node dist/update-known-versions/index.js node dist/update-known-versions/index.js
src/download/checksum/known-checksums.ts src/download/checksum/known-checksums.ts
version-manifest.json version-manifest.json
${{ secrets.GITHUB_TOKEN }}
- name: Check for changes - name: Check for changes
id: changes-exist id: changes-exist
run: | run: |
@@ -54,7 +55,7 @@ jobs:
- name: Create Pull Request - name: Create Pull Request
if: ${{ steps.changes-exist.outputs.changes-exist == 'true' && steps.commit-and-push.outcome != 'success' }} if: ${{ steps.changes-exist.outputs.changes-exist == 'true' && steps.commit-and-push.outcome != 'success' }}
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9
with: with:
commit-message: "chore: update known checksums" commit-message: "chore: update known checksums"
title: title:

View File

@@ -17,7 +17,7 @@ jobs:
permissions: permissions:
contents: write contents: write
steps: steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: true # needed for git push below persist-credentials: true # needed for git push below
- name: Update Major Minor Tags - name: Update Major Minor Tags

View File

@@ -1 +0,0 @@
.github/copilot-instructions.md

View File

@@ -125,8 +125,6 @@ Have a look under [Advanced Configuration](#advanced-configuration) for detailed
- `uvx-path`: The path to the installed uvx binary. - `uvx-path`: The path to the installed uvx binary.
- `cache-hit`: A boolean value to indicate a cache entry was found. - `cache-hit`: A boolean value to indicate a cache entry was found.
- `venv`: Path to the activated venv if activate-environment is true. - `venv`: Path to the activated venv if activate-environment is true.
- `python-version`: The Python version that was set.
- `python-cache-hit`: A boolean value to indicate the Python cache entry was found.
### Python version ### Python version
@@ -202,8 +200,7 @@ by name (`uv`).
With `setup-uv`, you can install a specific version of Python using `uv python install` rather than With `setup-uv`, you can install a specific version of Python using `uv python install` rather than
relying on `actions/setup-python`. relying on `actions/setup-python`.
Using `actions/setup-python` can be faster (~1s), because GitHub includes several Python versions in the runner image Using `actions/setup-python` can be faster, because GitHub caches the Python versions alongside the runner.
which are available to get activated by `actions/setup-python` without having to download them.
For example: For example:

View File

@@ -1,142 +0,0 @@
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
// biome-ignore lint/suspicious/noExplicitAny: mock needs flexible typing
const mockFetch = jest.fn<any>();
jest.mock("../../src/utils/fetch", () => ({
fetch: mockFetch,
}));
import {
clearCache,
fetchVersionData,
getAllVersions,
getArtifact,
getLatestVersion,
} from "../../src/download/versions-client";
const sampleNdjsonResponse = `{"version":"0.9.26","artifacts":[{"platform":"aarch64-apple-darwin","variant":"default","url":"https://github.com/astral-sh/uv/releases/download/0.9.26/uv-aarch64-apple-darwin.tar.gz","archive_format":"tar.gz","sha256":"fcf0a9ea6599c6ae28a4c854ac6da76f2c889354d7c36ce136ef071f7ab9721f"},{"platform":"x86_64-pc-windows-msvc","variant":"default","url":"https://github.com/astral-sh/uv/releases/download/0.9.26/uv-x86_64-pc-windows-msvc.zip","archive_format":"zip","sha256":"eb02fd95d8e0eed462b4a67ecdd320d865b38c560bffcda9a0b87ec944bdf036"}]}
{"version":"0.9.25","artifacts":[{"platform":"aarch64-apple-darwin","variant":"default","url":"https://github.com/astral-sh/uv/releases/download/0.9.25/uv-aarch64-apple-darwin.tar.gz","archive_format":"tar.gz","sha256":"606b3c6949d971709f2526fa0d9f0fd23ccf60e09f117999b406b424af18a6a6"}]}`;
function createMockResponse(
ok: boolean,
status: number,
statusText: string,
data: string,
) {
return {
ok,
status,
statusText,
text: async () => data,
};
}
describe("versions-client", () => {
beforeEach(() => {
clearCache();
mockFetch.mockReset();
});
describe("fetchVersionData", () => {
it("should fetch and parse NDJSON data", async () => {
mockFetch.mockResolvedValue(
createMockResponse(true, 200, "OK", sampleNdjsonResponse),
);
const versions = await fetchVersionData();
expect(versions).toHaveLength(2);
expect(versions[0].version).toBe("0.9.26");
expect(versions[1].version).toBe("0.9.25");
});
it("should throw error on failed fetch", async () => {
mockFetch.mockResolvedValue(
createMockResponse(false, 500, "Internal Server Error", ""),
);
await expect(fetchVersionData()).rejects.toThrow(
"Failed to fetch version data: 500 Internal Server Error",
);
});
it("should cache results", async () => {
mockFetch.mockResolvedValue(
createMockResponse(true, 200, "OK", sampleNdjsonResponse),
);
await fetchVersionData();
await fetchVersionData();
expect(mockFetch).toHaveBeenCalledTimes(1);
});
});
describe("getLatestVersion", () => {
it("should return the first version (newest)", async () => {
mockFetch.mockResolvedValue(
createMockResponse(true, 200, "OK", sampleNdjsonResponse),
);
const latest = await getLatestVersion();
expect(latest).toBe("0.9.26");
});
});
describe("getAllVersions", () => {
it("should return all version strings", async () => {
mockFetch.mockResolvedValue(
createMockResponse(true, 200, "OK", sampleNdjsonResponse),
);
const versions = await getAllVersions();
expect(versions).toEqual(["0.9.26", "0.9.25"]);
});
});
describe("getArtifact", () => {
beforeEach(() => {
mockFetch.mockResolvedValue(
createMockResponse(true, 200, "OK", sampleNdjsonResponse),
);
});
it("should find artifact by version and platform", async () => {
const artifact = await getArtifact("0.9.26", "aarch64", "apple-darwin");
expect(artifact).toEqual({
sha256:
"fcf0a9ea6599c6ae28a4c854ac6da76f2c889354d7c36ce136ef071f7ab9721f",
url: "https://github.com/astral-sh/uv/releases/download/0.9.26/uv-aarch64-apple-darwin.tar.gz",
});
});
it("should find Windows artifact", async () => {
const artifact = await getArtifact("0.9.26", "x86_64", "pc-windows-msvc");
expect(artifact).toEqual({
sha256:
"eb02fd95d8e0eed462b4a67ecdd320d865b38c560bffcda9a0b87ec944bdf036",
url: "https://github.com/astral-sh/uv/releases/download/0.9.26/uv-x86_64-pc-windows-msvc.zip",
});
});
it("should return undefined for unknown version", async () => {
const artifact = await getArtifact("0.0.1", "aarch64", "apple-darwin");
expect(artifact).toBeUndefined();
});
it("should return undefined for unknown platform", async () => {
const artifact = await getArtifact(
"0.9.26",
"aarch64",
"unknown-linux-musl",
);
expect(artifact).toBeUndefined();
});
});
});

View File

@@ -9,5 +9,5 @@ dependencies = [
] ]
[build-system] [build-system]
requires = ["uv_build>=0.9.22,<0.10.0"] requires = ["hatchling"]
build-backend = "uv_build" build-backend = "hatchling.build"

View File

@@ -1,9 +1,33 @@
version = 1 version = 1
revision = 3 requires-python = ">=3.12"
requires-python = ">=3.8, <=3.9"
[[package]] [[package]]
name = "old-python-constraint-project" name = "ruff"
version = "0.6.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/23/f4/279d044f66b79261fd37df76bf72b64471afab5d3b7906a01499c4451910/ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be", size = 2460281 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/72/4b/47dd7a69287afb4069fa42c198e899463605460a58120196711bfcf0446b/ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c", size = 9695871 },
{ url = "https://files.pythonhosted.org/packages/ae/c3/8aac62ac4638c14a740ee76a755a925f2d0d04580ab790a9887accb729f6/ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570", size = 9459354 },
{ url = "https://files.pythonhosted.org/packages/2f/cf/77fbd8d4617b9b9c503f9bffb8552c4e3ea1a58dc36975e7a9104ffb0f85/ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158", size = 9163871 },
{ url = "https://files.pythonhosted.org/packages/05/1c/765192bab32b79efbb498b06f0b9dcb3629112b53b8777ae1d19b8209e09/ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534", size = 10096250 },
{ url = "https://files.pythonhosted.org/packages/08/d0/86f3cb0f6934c99f759c232984a5204d67a26745cad2d9edff6248adf7d2/ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b", size = 9475376 },
{ url = "https://files.pythonhosted.org/packages/cd/cc/4c8d0e225b559a3fae6092ec310d7150d3b02b4669e9223f783ef64d82c0/ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d", size = 10295634 },
{ url = "https://files.pythonhosted.org/packages/db/96/d2699cfb1bb5a01c68122af43454c76c31331e1c8a9bd97d653d7c82524b/ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66", size = 11024941 },
{ url = "https://files.pythonhosted.org/packages/8b/a9/6ecd66af8929e0f2a1ed308a4137f3521789f28f0eb97d32c2ca3aa7000c/ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8", size = 10606894 },
{ url = "https://files.pythonhosted.org/packages/e4/73/2ee4cd19f44992fedac1cc6db9e3d825966072f6dcbd4032f21cbd063170/ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1", size = 11552886 },
{ url = "https://files.pythonhosted.org/packages/60/4c/c0f1cd35ce4a93c54a6bb1ee6934a3a205fa02198dd076678193853ceea1/ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1", size = 10264945 },
{ url = "https://files.pythonhosted.org/packages/c4/89/e45c9359b9cdd4245512ea2b9f2bb128a997feaa5f726fc9e8c7a66afadf/ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23", size = 10100007 },
{ url = "https://files.pythonhosted.org/packages/06/74/0bd4e0a7ed5f6908df87892f9bf60a2356c0fd74102d8097298bd9b4f346/ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a", size = 9559267 },
{ url = "https://files.pythonhosted.org/packages/54/03/3dc6dc9419f276f05805bf888c279e3e0b631284abd548d9e87cebb93aec/ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c", size = 9905304 },
{ url = "https://files.pythonhosted.org/packages/5c/5b/d6a72a6a6bbf097c09de468326ef5fa1c9e7aa5e6e45979bc0d984b0dbe7/ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56", size = 10341480 },
{ url = "https://files.pythonhosted.org/packages/79/a9/0f2f21fe15ba537c46598f96aa9ae4a3d4b9ec64926664617ca6a8c772f4/ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da", size = 7961901 },
{ url = "https://files.pythonhosted.org/packages/b0/80/fff12ffe11853d9f4ea3e5221e6dd2e93640a161c05c9579833e09ad40a7/ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2", size = 8783320 },
{ url = "https://files.pythonhosted.org/packages/56/91/577cdd64cce5e74d3f8b5ecb93f29566def569c741eb008aed4f331ef821/ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9", size = 8225886 },
]
[[package]]
name = "uv-project"
version = "0.1.0" version = "0.1.0"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
@@ -11,30 +35,4 @@ dependencies = [
] ]
[package.metadata] [package.metadata]
requires-dist = [{ name = "ruff", specifier = ">=0.6.2" }] requires-dist = [{ name = "ruff" }]
[[package]]
name = "ruff"
version = "0.14.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" },
{ url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" },
{ url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" },
{ url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" },
{ url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" },
{ url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" },
{ url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" },
{ url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" },
{ url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" },
{ url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" },
{ url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" },
{ url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" },
{ url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" },
{ url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" },
{ url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" },
{ url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" },
{ url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" },
{ url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" },
]

View File

@@ -1,75 +0,0 @@
# See https://github.com/typesafegithub/github-actions-typing
inputs:
version:
type: string
version-file:
type: string
python-version:
type: string
activate-environment:
type: boolean
working-directory:
type: string
checksum:
type: string
github-token:
type: string
enable-cache:
type: enum
allowed-values:
- "true"
- "false"
- auto
cache-dependency-glob:
type: list
separator: "\n"
list-item:
type: string
restore-cache:
type: boolean
save-cache:
type: boolean
cache-suffix:
type: string
cache-local-path:
type: string
prune-cache:
type: boolean
cache-python:
type: boolean
ignore-nothing-to-cache:
type: boolean
ignore-empty-workdir:
type: boolean
tool-dir:
type: string
tool-bin-dir:
type: string
manifest-file:
type: string
add-problem-matchers:
type: boolean
resolution-strategy:
type: enum
allowed-values:
- highest
- lowest
outputs:
uv-version:
type: string
uv-path:
type: string
uvx-path:
type: string
cache-hit:
type: boolean
cache-key:
type: string
venv:
type: string
python-version:
type: string
python-cache-hit:
type: boolean

View File

@@ -89,14 +89,8 @@ outputs:
description: "The path to the installed uvx binary." description: "The path to the installed uvx binary."
cache-hit: cache-hit:
description: "A boolean value to indicate a cache entry was found" description: "A boolean value to indicate a cache entry was found"
cache-key:
description: "The cache key used for storing/restoring the cache"
venv: venv:
description: "Path to the activated venv if activate-environment is true" description: "Path to the activated venv if activate-environment is true"
python-version:
description: "The Python version that was set."
python-cache-hit:
description: "A boolean value to indicate the Python cache entry was found"
runs: runs:
using: "node24" using: "node24"
main: "dist/setup/index.js" main: "dist/setup/index.js"

233
dist/save-cache/index.js generated vendored
View File

@@ -90599,52 +90599,45 @@ var __importStar = (this && this.__importStar) || (function () {
}; };
})(); })();
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.STATE_PYTHON_CACHE_MATCHED_KEY = exports.STATE_CACHE_MATCHED_KEY = exports.STATE_CACHE_KEY = void 0; exports.STATE_CACHE_MATCHED_KEY = exports.STATE_CACHE_KEY = void 0;
exports.restoreCache = restoreCache; exports.restoreCache = restoreCache;
const cache = __importStar(__nccwpck_require__(5116)); const cache = __importStar(__nccwpck_require__(5116));
const core = __importStar(__nccwpck_require__(7484)); const core = __importStar(__nccwpck_require__(7484));
const exec = __importStar(__nccwpck_require__(5236));
const hash_files_1 = __nccwpck_require__(9660); const hash_files_1 = __nccwpck_require__(9660);
const inputs_1 = __nccwpck_require__(9612); const inputs_1 = __nccwpck_require__(9612);
const platforms_1 = __nccwpck_require__(8361); const platforms_1 = __nccwpck_require__(8361);
exports.STATE_CACHE_KEY = "cache-key"; exports.STATE_CACHE_KEY = "cache-key";
exports.STATE_CACHE_MATCHED_KEY = "cache-matched-key"; exports.STATE_CACHE_MATCHED_KEY = "cache-matched-key";
exports.STATE_PYTHON_CACHE_MATCHED_KEY = "python-cache-matched-key"; const CACHE_VERSION = "1";
const CACHE_VERSION = "2"; async function restoreCache() {
async function restoreCache(pythonVersion) { const cacheKey = await computeKeys();
const cacheKey = await computeKeys(pythonVersion);
core.saveState(exports.STATE_CACHE_KEY, cacheKey); core.saveState(exports.STATE_CACHE_KEY, cacheKey);
core.setOutput("cache-key", cacheKey);
if (!inputs_1.restoreCache) { if (!inputs_1.restoreCache) {
core.info("restore-cache is false. Skipping restore cache step."); core.info("restore-cache is false. Skipping restore cache step.");
core.setOutput("python-cache-hit", false);
return; return;
} }
let matchedKey;
core.info(`Trying to restore uv cache from GitHub Actions cache with key: ${cacheKey}`);
if (inputs_1.cacheLocalPath === undefined) { if (inputs_1.cacheLocalPath === undefined) {
throw new Error("cache-local-path is not set. Cannot restore cache without a valid cache path."); throw new Error("cache-local-path is not set. Cannot restore cache without a valid cache path.");
} }
await restoreCacheFromKey(cacheKey, inputs_1.cacheLocalPath.path, exports.STATE_CACHE_MATCHED_KEY, "cache-hit"); const cachePaths = [inputs_1.cacheLocalPath.path];
if (inputs_1.cachePython) { if (inputs_1.cachePython) {
await restoreCacheFromKey(`${cacheKey}-python`, inputs_1.pythonDir, exports.STATE_PYTHON_CACHE_MATCHED_KEY, "python-cache-hit"); cachePaths.push(inputs_1.pythonDir);
} }
else {
core.setOutput("python-cache-hit", false);
}
}
async function restoreCacheFromKey(cacheKey, cachePath, stateKey, outputKey) {
core.info(`Trying to restore cache from GitHub Actions cache with key: ${cacheKey}`);
let matchedKey;
try { try {
matchedKey = await cache.restoreCache([cachePath], cacheKey); matchedKey = await cache.restoreCache(cachePaths, cacheKey);
} }
catch (err) { catch (err) {
const message = err.message; const message = err.message;
core.warning(message); core.warning(message);
core.setOutput(outputKey, false); core.setOutput("cache-hit", false);
return; return;
} }
handleMatchResult(matchedKey, cacheKey, stateKey, outputKey); handleMatchResult(matchedKey, cacheKey);
} }
async function computeKeys(pythonVersion) { async function computeKeys() {
let cacheDependencyPathHash = "-"; let cacheDependencyPathHash = "-";
if (inputs_1.cacheDependencyGlob !== "") { if (inputs_1.cacheDependencyGlob !== "") {
core.info(`Searching files using cache dependency glob: ${inputs_1.cacheDependencyGlob.split("\n").join(",")}`); core.info(`Searching files using cache dependency glob: ${inputs_1.cacheDependencyGlob.split("\n").join(",")}`);
@@ -90657,22 +90650,49 @@ async function computeKeys(pythonVersion) {
cacheDependencyPathHash = "-no-dependency-glob"; cacheDependencyPathHash = "-no-dependency-glob";
} }
const suffix = inputs_1.cacheSuffix ? `-${inputs_1.cacheSuffix}` : ""; const suffix = inputs_1.cacheSuffix ? `-${inputs_1.cacheSuffix}` : "";
const version = pythonVersion ?? "unknown"; const pythonVersion = await getPythonVersion();
const platform = await (0, platforms_1.getPlatform)(); const platform = await (0, platforms_1.getPlatform)();
const osNameVersion = (0, platforms_1.getOSNameVersion)();
const pruned = inputs_1.pruneCache ? "-pruned" : ""; const pruned = inputs_1.pruneCache ? "-pruned" : "";
const python = inputs_1.cachePython ? "-py" : ""; const python = inputs_1.cachePython ? "-py" : "";
return `setup-uv-${CACHE_VERSION}-${(0, platforms_1.getArch)()}-${platform}-${osNameVersion}-${version}${pruned}${python}${cacheDependencyPathHash}${suffix}`; return `setup-uv-${CACHE_VERSION}-${(0, platforms_1.getArch)()}-${platform}-${pythonVersion}${pruned}${python}${cacheDependencyPathHash}${suffix}`;
} }
function handleMatchResult(matchedKey, primaryKey, stateKey, outputKey) { async function getPythonVersion() {
if (inputs_1.pythonVersion !== "") {
return inputs_1.pythonVersion;
}
let output = "";
const options = {
listeners: {
stdout: (data) => {
output += data.toString();
},
},
silent: !core.isDebug(),
};
try {
const execArgs = ["python", "find", "--directory", inputs_1.workingDirectory];
await exec.exec("uv", execArgs, options);
const pythonPath = output.trim();
output = "";
await exec.exec(pythonPath, ["--version"], options);
// output is like "Python 3.8.10"
return output.split(" ")[1].trim();
}
catch (error) {
const err = error;
core.debug(`Failed to get python version from uv. Error: ${err.message}`);
return "unknown";
}
}
function handleMatchResult(matchedKey, primaryKey) {
if (!matchedKey) { if (!matchedKey) {
core.info(`No GitHub Actions cache found for key: ${primaryKey}`); core.info(`No GitHub Actions cache found for key: ${primaryKey}`);
core.setOutput(outputKey, false); core.setOutput("cache-hit", false);
return; return;
} }
core.saveState(stateKey, matchedKey); core.saveState(exports.STATE_CACHE_MATCHED_KEY, matchedKey);
core.info(`cache restored from GitHub Actions cache with key: ${matchedKey}`); core.info(`uv cache restored from GitHub Actions cache with key: ${matchedKey}`);
core.setOutput(outputKey, true); core.setOutput("cache-hit", true);
} }
@@ -90846,17 +90866,46 @@ async function saveCache() {
} }
if (matchedKey === cacheKey) { if (matchedKey === cacheKey) {
core.info(`Cache hit occurred on key ${cacheKey}, not saving cache.`); core.info(`Cache hit occurred on key ${cacheKey}, not saving cache.`);
return;
} }
else { if (inputs_1.pruneCache) {
if (inputs_1.pruneCache) { await pruneCache();
await pruneCache();
}
const actualCachePath = getUvCachePath();
await saveCacheToKey(cacheKey, actualCachePath, restore_cache_1.STATE_CACHE_MATCHED_KEY, "uv cache", `Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`);
} }
if (inputs_1.cacheLocalPath === undefined) {
throw new Error("cache-local-path is not set. Cannot save cache without a valid cache path.");
}
let actualCachePath = inputs_1.cacheLocalPath.path;
if (process.env.UV_CACHE_DIR &&
process.env.UV_CACHE_DIR !== inputs_1.cacheLocalPath.path) {
core.warning(`The environment variable UV_CACHE_DIR has been changed to "${process.env.UV_CACHE_DIR}", by an action or step running after astral-sh/setup-uv. This can lead to unexpected behavior. If you expected this to happen set the cache-local-path input to "${process.env.UV_CACHE_DIR}" instead of "${inputs_1.cacheLocalPath.path}".`);
actualCachePath = process.env.UV_CACHE_DIR;
}
core.info(`Saving cache path: ${actualCachePath}`);
if (!fs.existsSync(actualCachePath) && !inputs_1.ignoreNothingToCache) {
throw new Error(`Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`);
}
const cachePaths = [actualCachePath];
if (inputs_1.cachePython) { if (inputs_1.cachePython) {
const pythonCacheKey = `${cacheKey}-python`; core.info(`Including Python cache path: ${inputs_1.pythonDir}`);
await saveCacheToKey(pythonCacheKey, inputs_1.pythonDir, restore_cache_1.STATE_PYTHON_CACHE_MATCHED_KEY, "Python cache", `Python cache path ${inputs_1.pythonDir} does not exist on disk. This likely indicates that there are no Python installations to cache. Consider disabling the cache input if it is not needed.`); if (!fs.existsSync(inputs_1.pythonDir) && !inputs_1.ignoreNothingToCache) {
throw new Error(`Python cache path ${inputs_1.pythonDir} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`);
}
cachePaths.push(inputs_1.pythonDir);
}
core.info(`Final cache paths: ${cachePaths.join(", ")}`);
try {
await cache.saveCache(cachePaths, cacheKey);
core.info(`cache saved with the key: ${cacheKey}`);
}
catch (e) {
if (e instanceof Error &&
e.message ===
"Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.") {
core.info("No cacheable paths were found. Ignoring because ignore-nothing-to-save is enabled.");
}
else {
throw e;
}
} }
} }
async function pruneCache() { async function pruneCache() {
@@ -90872,42 +90921,6 @@ async function pruneCache() {
const uvPath = core.getState(constants_1.STATE_UV_PATH); const uvPath = core.getState(constants_1.STATE_UV_PATH);
await exec.exec(uvPath, execArgs, options); await exec.exec(uvPath, execArgs, options);
} }
function getUvCachePath() {
if (inputs_1.cacheLocalPath === undefined) {
throw new Error("cache-local-path is not set. Cannot save cache without a valid cache path.");
}
if (process.env.UV_CACHE_DIR &&
process.env.UV_CACHE_DIR !== inputs_1.cacheLocalPath.path) {
core.warning(`The environment variable UV_CACHE_DIR has been changed to "${process.env.UV_CACHE_DIR}", by an action or step running after astral-sh/setup-uv. This can lead to unexpected behavior. If you expected this to happen set the cache-local-path input to "${process.env.UV_CACHE_DIR}" instead of "${inputs_1.cacheLocalPath.path}".`);
return process.env.UV_CACHE_DIR;
}
return inputs_1.cacheLocalPath.path;
}
async function saveCacheToKey(cacheKey, cachePath, stateKey, cacheName, pathNotExistErrorMessage) {
const matchedKey = core.getState(stateKey);
if (matchedKey === cacheKey) {
core.info(`${cacheName} hit occurred on key ${cacheKey}, not saving cache.`);
return;
}
core.info(`Including ${cacheName} path: ${cachePath}`);
if (!fs.existsSync(cachePath) && !inputs_1.ignoreNothingToCache) {
throw new Error(pathNotExistErrorMessage);
}
try {
await cache.saveCache([cachePath], cacheKey);
core.info(`${cacheName} saved with key: ${cacheKey}`);
}
catch (e) {
if (e instanceof Error &&
e.message ===
"Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.") {
core.info(`No cacheable ${cacheName} paths were found. Ignoring because ignore-nothing-to-save is enabled.`);
}
else {
throw e;
}
}
}
run(); run();
@@ -90980,13 +90993,12 @@ function getConfigValueFromTomlFile(filePath, key) {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.VERSIONS_NDJSON_URL = exports.STATE_UV_VERSION = exports.STATE_UV_PATH = exports.TOOL_CACHE_NAME = exports.OWNER = exports.REPO = void 0; exports.STATE_UV_VERSION = exports.STATE_UV_PATH = exports.TOOL_CACHE_NAME = exports.OWNER = exports.REPO = void 0;
exports.REPO = "uv"; exports.REPO = "uv";
exports.OWNER = "astral-sh"; exports.OWNER = "astral-sh";
exports.TOOL_CACHE_NAME = "uv"; exports.TOOL_CACHE_NAME = "uv";
exports.STATE_UV_PATH = "uv-path"; exports.STATE_UV_PATH = "uv-path";
exports.STATE_UV_VERSION = "uv-version"; exports.STATE_UV_VERSION = "uv-version";
exports.VERSIONS_NDJSON_URL = "https://raw.githubusercontent.com/astral-sh/versions/main/v1/uv.ndjson";
/***/ }), /***/ }),
@@ -91170,7 +91182,7 @@ function getCacheDirFromConfig() {
} }
function getUvPythonDir() { function getUvPythonDir() {
if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) { if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) {
core.info(`UV_PYTHON_INSTALL_DIR is already set to ${process.env.UV_PYTHON_INSTALL_DIR}`); core.info(`UV_PYTHON_INSTALL_DIR is already set to ${process.env.UV_PYTHON_INSTALL_DIR}`);
return process.env.UV_PYTHON_INSTALL_DIR; return process.env.UV_PYTHON_INSTALL_DIR;
} }
if (process.env.RUNNER_ENVIRONMENT !== "github-hosted") { if (process.env.RUNNER_ENVIRONMENT !== "github-hosted") {
@@ -91270,15 +91282,9 @@ var __importStar = (this && this.__importStar) || (function () {
return result; return result;
}; };
})(); })();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getArch = getArch; exports.getArch = getArch;
exports.getPlatform = getPlatform; exports.getPlatform = getPlatform;
exports.getOSNameVersion = getOSNameVersion;
const node_fs_1 = __importDefault(__nccwpck_require__(3024));
const node_os_1 = __importDefault(__nccwpck_require__(8161));
const core = __importStar(__nccwpck_require__(7484)); const core = __importStar(__nccwpck_require__(7484));
const exec = __importStar(__nccwpck_require__(5236)); const exec = __importStar(__nccwpck_require__(5236));
function getArch() { function getArch() {
@@ -91336,63 +91342,6 @@ async function isMuslOs() {
return false; return false;
} }
} }
/**
* Returns OS name and version for cache key differentiation.
* Examples: "ubuntu-22.04", "macos-14", "windows-2022"
* Throws if OS detection fails.
*/
function getOSNameVersion() {
const platform = process.platform;
if (platform === "linux") {
return getLinuxOSNameVersion();
}
if (platform === "darwin") {
return getMacOSNameVersion();
}
if (platform === "win32") {
return getWindowsNameVersion();
}
throw new Error(`Unsupported platform: ${platform}`);
}
function getLinuxOSNameVersion() {
const files = ["/etc/os-release", "/usr/lib/os-release"];
for (const file of files) {
try {
const content = node_fs_1.default.readFileSync(file, "utf8");
const id = parseOsReleaseValue(content, "ID");
const versionId = parseOsReleaseValue(content, "VERSION_ID");
if (id && versionId) {
return `${id}-${versionId}`;
}
}
catch {
// Try next file
}
}
throw new Error("Failed to determine Linux distribution. " +
"Could not read /etc/os-release or /usr/lib/os-release");
}
function parseOsReleaseValue(content, key) {
const regex = new RegExp(`^${key}=["']?([^"'\\n]*)["']?$`, "m");
const match = content.match(regex);
return match?.[1];
}
function getMacOSNameVersion() {
const darwinVersion = Number.parseInt(node_os_1.default.release().split(".")[0], 10);
if (Number.isNaN(darwinVersion)) {
throw new Error(`Failed to parse macOS version from: ${node_os_1.default.release()}`);
}
const macosVersion = darwinVersion - 9;
return `macos-${macosVersion}`;
}
function getWindowsNameVersion() {
const version = node_os_1.default.version();
const match = version.match(/Windows(?: Server)? (\d+)/);
if (!match) {
throw new Error(`Failed to parse Windows version from: ${version}`);
}
return `windows-${match[1]}`;
}
/***/ }), /***/ }),
@@ -91533,14 +91482,6 @@ module.exports = require("node:fs");
/***/ }), /***/ }),
/***/ 8161:
/***/ ((module) => {
"use strict";
module.exports = require("node:os");
/***/ }),
/***/ 6760: /***/ 6760:
/***/ ((module) => { /***/ ((module) => {

4824
dist/setup/index.js generated vendored

File diff suppressed because it is too large Load Diff

9406
dist/update-known-versions/index.js generated vendored

File diff suppressed because it is too large Load Diff

View File

@@ -2,34 +2,6 @@
This document covers all caching-related configuration options for setup-uv. This document covers all caching-related configuration options for setup-uv.
## Cache key
The cache key is automatically generated based on:
- **Architecture**: CPU architecture (e.g., `x86_64`, `aarch64`)
- **Platform**: OS platform type (e.g., `unknown-linux-gnu`, `unknown-linux-musl`, `apple-darwin`,
`pc-windows-msvc`)
- **OS version**: OS name and version (e.g., `ubuntu-22.04`, `macos-14`, `windows-2022`)
- **Python version**: The Python version in use
- **Cache options**: Whether pruning and Python caching are enabled
- **Dependency hash**: Hash of files matching `cache-dependency-glob`
- **Suffix**: Optional `cache-suffix` if provided
Including the OS version ensures that caches are not shared between different OS versions,
preventing binary incompatibility issues when runner images change.
The computed cache key is available as the `cache-key` output:
```yaml
- name: Setup uv
id: setup-uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Print cache key
run: echo "Cache key: ${{ steps.setup-uv.outputs.cache-key }}"
```
## Enable caching ## Enable caching
> [!NOTE] > [!NOTE]

275
package-lock.json generated
View File

@@ -15,8 +15,11 @@
"@actions/glob": "^0.5.0", "@actions/glob": "^0.5.0",
"@actions/io": "^1.1.3", "@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.2", "@actions/tool-cache": "^2.0.2",
"@octokit/core": "^7.0.6",
"@octokit/plugin-paginate-rest": "^14.0.0",
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
"@renovatebot/pep440": "^4.2.1", "@renovatebot/pep440": "^4.2.1",
"smol-toml": "^1.4.2", "smol-toml": "^1.5.2",
"undici": "5.28.5" "undici": "5.28.5"
}, },
"devDependencies": { "devDependencies": {
@@ -1586,6 +1589,133 @@
"@tybys/wasm-util": "^0.10.0" "@tybys/wasm-util": "^0.10.0"
} }
}, },
"node_modules/@octokit/auth-token": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz",
"integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==",
"license": "MIT",
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/core": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
"integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
"license": "MIT",
"dependencies": {
"@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^9.0.3",
"@octokit/request": "^10.0.6",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"before-after-hook": "^4.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/endpoint": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz",
"integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/graphql": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
"integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^10.0.6",
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
"integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz",
"integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/request": {
"version": "10.0.7",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz",
"integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^11.0.2",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"fast-content-type-parse": "^3.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/request-error": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/@opentelemetry/api": { "node_modules/@opentelemetry/api": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
@@ -2322,6 +2452,12 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
}, },
"node_modules/before-after-hook": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
"integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==",
"license": "Apache-2.0"
},
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.12", "version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
@@ -2931,6 +3067,22 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
} }
}, },
"node_modules/fast-content-type-parse": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
"integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT"
},
"node_modules/fast-json-stable-stringify": { "node_modules/fast-json-stable-stringify": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -4751,10 +4903,9 @@
} }
}, },
"node_modules/smol-toml": { "node_modules/smol-toml": {
"version": "1.4.2", "version": "1.5.2",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.4.2.tgz", "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.2.tgz",
"integrity": "sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g==", "integrity": "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==",
"license": "BSD-3-Clause",
"engines": { "engines": {
"node": ">= 18" "node": ">= 18"
}, },
@@ -5213,6 +5364,12 @@
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/universal-user-agent": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
"license": "ISC"
},
"node_modules/unrs-resolver": { "node_modules/unrs-resolver": {
"version": "1.11.1", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz",
@@ -6723,6 +6880,93 @@
"@tybys/wasm-util": "^0.10.0" "@tybys/wasm-util": "^0.10.0"
} }
}, },
"@octokit/auth-token": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz",
"integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="
},
"@octokit/core": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
"integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
"requires": {
"@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^9.0.3",
"@octokit/request": "^10.0.6",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"before-after-hook": "^4.0.0",
"universal-user-agent": "^7.0.0"
}
},
"@octokit/endpoint": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz",
"integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==",
"requires": {
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.2"
}
},
"@octokit/graphql": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
"integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
"requires": {
"@octokit/request": "^10.0.6",
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.0"
}
},
"@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="
},
"@octokit/plugin-paginate-rest": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
"integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
"requires": {
"@octokit/types": "^16.0.0"
}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz",
"integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==",
"requires": {
"@octokit/types": "^16.0.0"
}
},
"@octokit/request": {
"version": "10.0.7",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz",
"integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==",
"requires": {
"@octokit/endpoint": "^11.0.2",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"fast-content-type-parse": "^3.0.0",
"universal-user-agent": "^7.0.2"
}
},
"@octokit/request-error": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
"requires": {
"@octokit/types": "^16.0.0"
}
},
"@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"requires": {
"@octokit/openapi-types": "^27.0.0"
}
},
"@opentelemetry/api": { "@opentelemetry/api": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
@@ -7223,6 +7467,11 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
}, },
"before-after-hook": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
"integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="
},
"brace-expansion": { "brace-expansion": {
"version": "1.1.12", "version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
@@ -7623,6 +7872,11 @@
"jest-util": "30.2.0" "jest-util": "30.2.0"
} }
}, },
"fast-content-type-parse": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
"integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="
},
"fast-json-stable-stringify": { "fast-json-stable-stringify": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -8867,9 +9121,9 @@
"dev": true "dev": true
}, },
"smol-toml": { "smol-toml": {
"version": "1.4.2", "version": "1.5.2",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.4.2.tgz", "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.2.tgz",
"integrity": "sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g==" "integrity": "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ=="
}, },
"source-map": { "source-map": {
"version": "0.6.1", "version": "0.6.1",
@@ -9156,6 +9410,11 @@
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==" "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="
}, },
"universal-user-agent": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="
},
"unrs-resolver": { "unrs-resolver": {
"version": "1.11.1", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz",

View File

@@ -10,7 +10,7 @@
"package": "ncc build -o dist/setup src/setup-uv.ts && ncc build -o dist/save-cache src/save-cache.ts && ncc build -o dist/update-known-versions src/update-known-versions.ts", "package": "ncc build -o dist/setup src/setup-uv.ts && ncc build -o dist/save-cache src/save-cache.ts && ncc build -o dist/update-known-versions src/update-known-versions.ts",
"test": "jest", "test": "jest",
"act": "act pull_request -W .github/workflows/test.yml --container-architecture linux/amd64 -s GITHUB_TOKEN=\"$(gh auth token)\"", "act": "act pull_request -W .github/workflows/test.yml --container-architecture linux/amd64 -s GITHUB_TOKEN=\"$(gh auth token)\"",
"update-known-versions": "RUNNER_TEMP=known_versions node dist/update-known-versions/index.js src/download/checksum/known-checksums.ts version-manifest.json", "update-known-versions": "RUNNER_TEMP=known_versions node dist/update-known-versions/index.js src/download/checksum/known-versions.ts \"$(gh auth token)\"",
"all": "npm run build && npm run check && npm run package && npm test" "all": "npm run build && npm run check && npm run package && npm test"
}, },
"repository": { "repository": {
@@ -32,8 +32,11 @@
"@actions/glob": "^0.5.0", "@actions/glob": "^0.5.0",
"@actions/io": "^1.1.3", "@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.2", "@actions/tool-cache": "^2.0.2",
"@octokit/core": "^7.0.6",
"@octokit/plugin-paginate-rest": "^14.0.0",
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
"@renovatebot/pep440": "^4.2.1", "@renovatebot/pep440": "^4.2.1",
"smol-toml": "^1.4.2", "smol-toml": "^1.5.2",
"undici": "5.28.5" "undici": "5.28.5"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,5 +1,6 @@
import * as cache from "@actions/cache"; import * as cache from "@actions/cache";
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as exec from "@actions/exec";
import { hashFiles } from "../hash/hash-files"; import { hashFiles } from "../hash/hash-files";
import { import {
cacheDependencyGlob, cacheDependencyGlob,
@@ -8,75 +9,51 @@ import {
cacheSuffix, cacheSuffix,
pruneCache, pruneCache,
pythonDir, pythonDir,
pythonVersion as pythonVersionInput,
restoreCache as shouldRestoreCache, restoreCache as shouldRestoreCache,
workingDirectory,
} from "../utils/inputs"; } from "../utils/inputs";
import { getArch, getOSNameVersion, getPlatform } from "../utils/platforms"; import { getArch, getPlatform } from "../utils/platforms";
export const STATE_CACHE_KEY = "cache-key"; export const STATE_CACHE_KEY = "cache-key";
export const STATE_CACHE_MATCHED_KEY = "cache-matched-key"; export const STATE_CACHE_MATCHED_KEY = "cache-matched-key";
export const STATE_PYTHON_CACHE_MATCHED_KEY = "python-cache-matched-key"; const CACHE_VERSION = "1";
const CACHE_VERSION = "2"; export async function restoreCache(): Promise<void> {
const cacheKey = await computeKeys();
export async function restoreCache(pythonVersion?: string): Promise<void> {
const cacheKey = await computeKeys(pythonVersion);
core.saveState(STATE_CACHE_KEY, cacheKey); core.saveState(STATE_CACHE_KEY, cacheKey);
core.setOutput("cache-key", cacheKey);
if (!shouldRestoreCache) { if (!shouldRestoreCache) {
core.info("restore-cache is false. Skipping restore cache step."); core.info("restore-cache is false. Skipping restore cache step.");
core.setOutput("python-cache-hit", false);
return; return;
} }
let matchedKey: string | undefined;
core.info(
`Trying to restore uv cache from GitHub Actions cache with key: ${cacheKey}`,
);
if (cacheLocalPath === undefined) { if (cacheLocalPath === undefined) {
throw new Error( throw new Error(
"cache-local-path is not set. Cannot restore cache without a valid cache path.", "cache-local-path is not set. Cannot restore cache without a valid cache path.",
); );
} }
const cachePaths = [cacheLocalPath.path];
await restoreCacheFromKey(
cacheKey,
cacheLocalPath.path,
STATE_CACHE_MATCHED_KEY,
"cache-hit",
);
if (cachePython) { if (cachePython) {
await restoreCacheFromKey( cachePaths.push(pythonDir);
`${cacheKey}-python`,
pythonDir,
STATE_PYTHON_CACHE_MATCHED_KEY,
"python-cache-hit",
);
} else {
core.setOutput("python-cache-hit", false);
} }
}
async function restoreCacheFromKey(
cacheKey: string,
cachePath: string,
stateKey: string,
outputKey: string,
): Promise<void> {
core.info(
`Trying to restore cache from GitHub Actions cache with key: ${cacheKey}`,
);
let matchedKey: string | undefined;
try { try {
matchedKey = await cache.restoreCache([cachePath], cacheKey); matchedKey = await cache.restoreCache(cachePaths, cacheKey);
} catch (err) { } catch (err) {
const message = (err as Error).message; const message = (err as Error).message;
core.warning(message); core.warning(message);
core.setOutput(outputKey, false); core.setOutput("cache-hit", false);
return; return;
} }
handleMatchResult(matchedKey, cacheKey, stateKey, outputKey); handleMatchResult(matchedKey, cacheKey);
} }
async function computeKeys(pythonVersion?: string): Promise<string> { async function computeKeys(): Promise<string> {
let cacheDependencyPathHash = "-"; let cacheDependencyPathHash = "-";
if (cacheDependencyGlob !== "") { if (cacheDependencyGlob !== "") {
core.info( core.info(
@@ -93,27 +70,57 @@ async function computeKeys(pythonVersion?: string): Promise<string> {
cacheDependencyPathHash = "-no-dependency-glob"; cacheDependencyPathHash = "-no-dependency-glob";
} }
const suffix = cacheSuffix ? `-${cacheSuffix}` : ""; const suffix = cacheSuffix ? `-${cacheSuffix}` : "";
const version = pythonVersion ?? "unknown"; const pythonVersion = await getPythonVersion();
const platform = await getPlatform(); const platform = await getPlatform();
const osNameVersion = getOSNameVersion();
const pruned = pruneCache ? "-pruned" : ""; const pruned = pruneCache ? "-pruned" : "";
const python = cachePython ? "-py" : ""; const python = cachePython ? "-py" : "";
return `setup-uv-${CACHE_VERSION}-${getArch()}-${platform}-${osNameVersion}-${version}${pruned}${python}${cacheDependencyPathHash}${suffix}`; return `setup-uv-${CACHE_VERSION}-${getArch()}-${platform}-${pythonVersion}${pruned}${python}${cacheDependencyPathHash}${suffix}`;
}
async function getPythonVersion(): Promise<string> {
if (pythonVersionInput !== "") {
return pythonVersionInput;
}
let output = "";
const options: exec.ExecOptions = {
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
},
},
silent: !core.isDebug(),
};
try {
const execArgs = ["python", "find", "--directory", workingDirectory];
await exec.exec("uv", execArgs, options);
const pythonPath = output.trim();
output = "";
await exec.exec(pythonPath, ["--version"], options);
// output is like "Python 3.8.10"
return output.split(" ")[1].trim();
} catch (error) {
const err = error as Error;
core.debug(`Failed to get python version from uv. Error: ${err.message}`);
return "unknown";
}
} }
function handleMatchResult( function handleMatchResult(
matchedKey: string | undefined, matchedKey: string | undefined,
primaryKey: string, primaryKey: string,
stateKey: string,
outputKey: string,
): void { ): void {
if (!matchedKey) { if (!matchedKey) {
core.info(`No GitHub Actions cache found for key: ${primaryKey}`); core.info(`No GitHub Actions cache found for key: ${primaryKey}`);
core.setOutput(outputKey, false); core.setOutput("cache-hit", false);
return; return;
} }
core.saveState(stateKey, matchedKey); core.saveState(STATE_CACHE_MATCHED_KEY, matchedKey);
core.info(`cache restored from GitHub Actions cache with key: ${matchedKey}`); core.info(
core.setOutput(outputKey, true); `uv cache restored from GitHub Actions cache with key: ${matchedKey}`,
);
core.setOutput("cache-hit", true);
} }

View File

@@ -11,36 +11,28 @@ export async function validateChecksum(
arch: Architecture, arch: Architecture,
platform: Platform, platform: Platform,
version: string, version: string,
ndjsonChecksum?: string,
): Promise<void> { ): Promise<void> {
// Priority: user-provided checksum > KNOWN_CHECKSUMS > NDJSON fallback let isValid: boolean | undefined;
const key = `${arch}-${platform}-${version}`;
let checksumToUse: string | undefined;
let source: string;
if (checkSum !== undefined && checkSum !== "") { if (checkSum !== undefined && checkSum !== "") {
checksumToUse = checkSum; isValid = await validateFileCheckSum(downloadPath, checkSum);
source = "user-provided";
} else if (key in KNOWN_CHECKSUMS) {
checksumToUse = KNOWN_CHECKSUMS[key];
source = `known checksum for ${key}`;
} else if (ndjsonChecksum !== undefined && ndjsonChecksum !== "") {
checksumToUse = ndjsonChecksum;
source = "NDJSON version data";
} else { } else {
core.debug(`No checksum found for ${key}.`); core.debug("Checksum not provided. Checking known checksums.");
return; const key = `${arch}-${platform}-${version}`;
if (key in KNOWN_CHECKSUMS) {
const knownChecksum = KNOWN_CHECKSUMS[`${arch}-${platform}-${version}`];
core.debug(`Checking checksum for ${arch}-${platform}-${version}.`);
isValid = await validateFileCheckSum(downloadPath, knownChecksum);
} else {
core.debug(`No known checksum found for ${key}.`);
}
} }
core.debug(`Using ${source}.`); if (isValid === false) {
const isValid = await validateFileCheckSum(downloadPath, checksumToUse); throw new Error(`Checksum for ${downloadPath} did not match ${checkSum}.`);
}
if (!isValid) { if (isValid === true) {
throw new Error( core.debug(`Checksum for ${downloadPath} is valid.`);
`Checksum for ${downloadPath} did not match ${checksumToUse}.`,
);
} }
core.debug(`Checksum for ${downloadPath} is valid.`);
} }
async function validateFileCheckSum( async function validateFileCheckSum(

View File

@@ -1,329 +1,5 @@
// AUTOGENERATED_DO_NOT_EDIT // AUTOGENERATED_DO_NOT_EDIT
export const KNOWN_CHECKSUMS: { [key: string]: string } = { export const KNOWN_CHECKSUMS: { [key: string]: string } = {
"aarch64-apple-darwin-0.9.26":
"fcf0a9ea6599c6ae28a4c854ac6da76f2c889354d7c36ce136ef071f7ab9721f",
"aarch64-pc-windows-msvc-0.9.26":
"79e1398ec98681b1b0494ed3485b0f4565e98a7db109a3f205d0fcdc6a1992f7",
"aarch64-unknown-linux-gnu-0.9.26":
"f71040c59798f79c44c08a7a1c1af7de95a8d334ea924b47b67ad6b9632be270",
"aarch64-unknown-linux-musl-0.9.26":
"ba8698c36c00c22efed4bd3506339b03c95604d001f02eaf6fbc814c9224d801",
"arm-unknown-linux-musleabihf-0.9.26":
"8baa850e6f7a4f8edeef411891780161e95682bf291c85405fdc331925c425c2",
"armv7-unknown-linux-gnueabihf-0.9.26":
"f9cf9806b3bd434b4aca5de1a8412502a29bcbc908848cdea18e32480964ab79",
"armv7-unknown-linux-musleabihf-0.9.26":
"881df52998da192f0609be37abe445ab0d89f28daceecb171ea8a14088153aee",
"i686-pc-windows-msvc-0.9.26":
"2fa5e36d7dc3053962a95a2583b2bcc19aab2ec6c5d4c887cca58de819cf77dd",
"i686-unknown-linux-gnu-0.9.26":
"03548a2abd1d604724c9d65184b506d3eafef1b0a7d8cea974a083f5f9c9496f",
"i686-unknown-linux-musl-0.9.26":
"5208601b9baee1a04a604f441bd94a1ab91b511f142b27729b073f4286994f8f",
"powerpc64-unknown-linux-gnu-0.9.26":
"6ac6baa2dd7db742ff58a2d54e3fc09693e69c878666bcacf9d49bc58decc98a",
"powerpc64le-unknown-linux-gnu-0.9.26":
"1a7fbd268b7520e03747022f879113545a5bd71cad02e9cbabd591b268b5a36c",
"riscv64gc-unknown-linux-gnu-0.9.26":
"9f202ad04cc398dc77a6efe20ea91ec044ad66e1f7a60777e6efd20a357f479a",
"s390x-unknown-linux-gnu-0.9.26":
"f8e6b8f1264821add1ea21d592b4522300401f44ac4124fba9fea6874fd79797",
"x86_64-apple-darwin-0.9.26":
"171eb8c518313e157c5b4cec7b4f743bc6bab1bd23e09b646679a02d096a047f",
"x86_64-pc-windows-msvc-0.9.26":
"eb02fd95d8e0eed462b4a67ecdd320d865b38c560bffcda9a0b87ec944bdf036",
"x86_64-unknown-linux-gnu-0.9.26":
"30ccbf0a66dc8727a02b0e245c583ee970bdafecf3a443c1686e1b30ec4939e8",
"x86_64-unknown-linux-musl-0.9.26":
"708b752876aeeb753257e1d55470569789e465684c1d3bc1760db26360b6c28b",
"aarch64-apple-darwin-0.9.25":
"606b3c6949d971709f2526fa0d9f0fd23ccf60e09f117999b406b424af18a6a6",
"aarch64-pc-windows-msvc-0.9.25":
"6a4c2a753a94d9639725b435f5d1a65bfa25cd196d448ad60841f5fe81ef0052",
"aarch64-unknown-linux-gnu-0.9.25":
"a8f1d71a42c4470251a880348b2d28d530018693324175084fa1749d267c98c6",
"aarch64-unknown-linux-musl-0.9.25":
"11cddffc61826e3b7af02db37bc3ed8e9e6747dad328d45c8b02f89408afbf75",
"arm-unknown-linux-musleabihf-0.9.25":
"52f3a96605a7873ec44bb84c33ee08e717df61136fec121f715871cae5b779ec",
"armv7-unknown-linux-gnueabihf-0.9.25":
"7ae274742a5b2398bd75f9075536c7f0b3f99ebc8c6588c37e3bfcd9cc9d781d",
"armv7-unknown-linux-musleabihf-0.9.25":
"77220a539dfffe576cdc9b9e9ab5432c07dd1b63915c859c227883af7ba00538",
"i686-pc-windows-msvc-0.9.25":
"55dbf32074a76e029410620e7e3fbef9762799c7dfcf539b098ccc0a64cac9a3",
"i686-unknown-linux-gnu-0.9.25":
"b9dae29f4e37bc89e69836e59169a51d8cac4da118b7548a20b2269b19c94cad",
"i686-unknown-linux-musl-0.9.25":
"a84a159856a0227c273e86594d9cf8fbf84c56bd4eeeb9a665c946304c49dbec",
"powerpc64-unknown-linux-gnu-0.9.25":
"37bc519ebe5e4efb12fd155eb94512547a874f0e41251203b49d715f75eb5a20",
"powerpc64le-unknown-linux-gnu-0.9.25":
"a01a273b5cd64ece96d4589afbacaf5e99a0695f37ebe9a72fd6b2f7cf0a7071",
"riscv64gc-unknown-linux-gnu-0.9.25":
"9d9692f1bd5ff6d9db2c4bffc4ceeb8d8746ae03ddeca0b24a0f8fc9ea81b911",
"s390x-unknown-linux-gnu-0.9.25":
"92d5e4504ef83f421a841381678f871bf2a8821a69d3374dd638e2014d4762ab",
"x86_64-apple-darwin-0.9.25":
"4982dfff14b3548bc85d0fa0abec6ab8ae62836b218bf1223741ba1392ef93bf",
"x86_64-pc-windows-msvc-0.9.25":
"d63f8e59cf76bcce9cb8a3eac6c1a89adce0f89a29bacca978c9bf842f419277",
"x86_64-unknown-linux-gnu-0.9.25":
"fa1f4abfe101d43e820342210c3c6854028703770f81e95b119ed1e65ec81b35",
"x86_64-unknown-linux-musl-0.9.25":
"700776c376ce36ed5b731fcd699e141d897551f5111907987b63897e0c1ad797",
"aarch64-apple-darwin-0.9.24":
"89661d9a16682197086df54bb43d0b03e58e23d4d9360fc8c6c0166f2828fd71",
"aarch64-pc-windows-msvc-0.9.24":
"40ceb66af2667fc9b4d30a65ad8b8795d4effc39a44019b4218ad03f8f1d5a14",
"aarch64-unknown-linux-gnu-0.9.24":
"9b291a1a4f2fefc430e4fc49c00cb93eb448d41c5c79edf45211ceffedde3334",
"aarch64-unknown-linux-musl-0.9.24":
"b16359904ede857b90b68168f10b0f6bf500858df9bed4e7156dbc59fd3f0747",
"arm-unknown-linux-musleabihf-0.9.24":
"b343d7f49ea5c0982c9696cbc5c7f96d7053cf8f9c7383a58d6c0c44fbeb6422",
"armv7-unknown-linux-gnueabihf-0.9.24":
"8d05b55fe2108ecab3995c2b656679a72c543fd9dc72eeb3a525106a709cfdcb",
"armv7-unknown-linux-musleabihf-0.9.24":
"788d2bee1dfdb57a462f2a5c4e3d6e8c68ee9f9f1a938bdcdc00fa9e5edeaeec",
"i686-pc-windows-msvc-0.9.24":
"b49265a713cb3f874bcb373572095993d3098ab77cd2665483f53b24b788e5e9",
"i686-unknown-linux-gnu-0.9.24":
"940b8985c4d464c7cc69e40b17bf09d840b980028e1d82a3fb8dd007a737f29e",
"i686-unknown-linux-musl-0.9.24":
"4ffe6f377b7d68904d8d882af8adc85f2fa1bbccd26151785ff961adb67f2a99",
"powerpc64-unknown-linux-gnu-0.9.24":
"1fbaff65544a2c36bbd8992e2abe6c50179401745dc00b5e12bded89794056a4",
"powerpc64le-unknown-linux-gnu-0.9.24":
"57ea84430ccf49f97184d9ee21102b250214fc6e6af4a87eefaaf8bb7c9c2b9a",
"riscv64gc-unknown-linux-gnu-0.9.24":
"81a884380f0ee954afd968140aaa55df19f2bee30d74f3c0c94a11d2265bb388",
"s390x-unknown-linux-gnu-0.9.24":
"3da41f22f78f27a7764e303b07c68f5716f748128327c7d3d72f11c6b81b6c78",
"x86_64-apple-darwin-0.9.24":
"fda9b3203cce6ec3a37177440c33c4c1963c4957fff17e2820c60ab6ccd625da",
"x86_64-pc-windows-msvc-0.9.24":
"cf9d6fa12017199d19c6f9a8f7f55811c8c04d70681b8cb6d89ffb179f08cf1f",
"x86_64-unknown-linux-gnu-0.9.24":
"fb13ad85106da6b21dd16613afca910994446fe94a78ee0b5bed9c75cd066078",
"x86_64-unknown-linux-musl-0.9.24":
"cf307aa4271038daa334ca64e75aa40c0c085ce6fa0c0e6f21e41a2b62c7904d",
"aarch64-apple-darwin-0.9.23":
"3aae069424778d13ef45ebd2ec906c66ab10e459e7b33341a64cd371a3d70998",
"aarch64-pc-windows-msvc-0.9.23":
"dfdb23dbfa6c89847e4163f0b3b683de889df7d9bdf95a3909dfbc6430106304",
"aarch64-unknown-linux-gnu-0.9.23":
"d60b0b2aee79f9d83897615fed427bee1ea4ebcb2f15b48dd522319ecdb3de91",
"aarch64-unknown-linux-musl-0.9.23":
"ee987d943427ee24c1d3af79c7ad676950c9ad634e60a4d07e328d8a54fff92f",
"arm-unknown-linux-musleabihf-0.9.23":
"1950c235e76e007f75d30903dc5da6747a344c72a1608123feff720c134ecbfe",
"armv7-unknown-linux-gnueabihf-0.9.23":
"a7104ab491a0c2f0c58760bcb9a13cfb64c899e02a7b747c4d11da114b3f9114",
"armv7-unknown-linux-musleabihf-0.9.23":
"c5d494337a5ca86ad83d6a887634fda3f8392560799e4236a44d76f8e27621b6",
"i686-pc-windows-msvc-0.9.23":
"94292f02b7484616bb3cd7361411540a5a52e952d149eb6faeec610b6657015d",
"i686-unknown-linux-gnu-0.9.23":
"627627174d31e6fa270e91c7b2988558e4b18b86cc31de9222b6cf3b7354e9b7",
"i686-unknown-linux-musl-0.9.23":
"5f65a0eb1f9067a4f5149275faba3bcb3af94dd68fbce7cd9e93ba86b5bc59c3",
"powerpc64-unknown-linux-gnu-0.9.23":
"69e2925397d0e781e8525ad0fd22896a114ffa02f5055e7a360e4dda3796c24e",
"powerpc64le-unknown-linux-gnu-0.9.23":
"fb3ad2cb1a19f1bb4785580dc71837161147beab134fdc3eb4e8ccda577db1e0",
"riscv64gc-unknown-linux-gnu-0.9.23":
"0d1d9300e2df3155b0d0b071c292fb27f8213d91854decdfb27c293397dc8e0e",
"s390x-unknown-linux-gnu-0.9.23":
"7d0b411a365b0cd8fad2b336c259743e7381676654adfbdb4f887b4136820cb8",
"x86_64-apple-darwin-0.9.23":
"b5bbfbd5d8c7effa24b505365ae306116fdac58880bc9b024ec4c89435d57728",
"x86_64-pc-windows-msvc-0.9.23":
"bb6d2987906b27d3031640c4a909b6f7c134cd29674c41ef545c6e7d57dd6700",
"x86_64-unknown-linux-gnu-0.9.23":
"b7bd7d9b9c9c34327f1118f99fe8c298252787ea35f7b345b8bf639377f63217",
"x86_64-unknown-linux-musl-0.9.23":
"a824a0f5f7aa67b668f54756284d458a25dea332da6e558d303890d134cc06d1",
"aarch64-apple-darwin-0.9.22":
"4bfc6dacc9bcc9e433a9214a658495ca082b94fd607949b6745a955f34ccbc3c",
"aarch64-pc-windows-msvc-0.9.22":
"19b848523d5802279702f5df4ade6d45f17d111cf9e368883d4f6560f0426d49",
"aarch64-unknown-linux-gnu-0.9.22":
"2f8716c407d5da21b8a3e8609ed358147216aaab28b96b1d6d7f48e9bcc6254e",
"aarch64-unknown-linux-musl-0.9.22":
"a400eaede62557af86bed6c5252a101aa1efd596698bb10c9400334fcc2847ec",
"arm-unknown-linux-musleabihf-0.9.22":
"23e0770034e31aaf47b0c84156b2e5ec7638ca0edc76a4cccb8bdc94bfd16159",
"armv7-unknown-linux-gnueabihf-0.9.22":
"db3ac49b78b3ac57c0e6e9a0ea61237a235447338594ad8e398e8074448bd071",
"armv7-unknown-linux-musleabihf-0.9.22":
"c153ac78c571dbbd9bab54c954b93b496645efbd4d3a0689b03e04d0de17c30f",
"i686-pc-windows-msvc-0.9.22":
"f08889e9567feb1e802c9e588de60efef5a436630e4c211fbf4a2116928f69ab",
"i686-unknown-linux-gnu-0.9.22":
"841e534a28285dcadfea2ca0f848a9669df287990f93d64c6bf87a9794c98ec9",
"i686-unknown-linux-musl-0.9.22":
"b2c5322e188980afd4bc1afb19f4e8dee7000ad0e17ca754e97dab21c1d4d1f5",
"powerpc64-unknown-linux-gnu-0.9.22":
"309c4a48d7f65cdf47aa7e1c5e02502556e04f486d46e9591f5b4196c92730a3",
"powerpc64le-unknown-linux-gnu-0.9.22":
"1e829630f8317cf3e9818c3ad1f9927fdc9d087cd38abb05f9587c19872a8560",
"riscv64gc-unknown-linux-gnu-0.9.22":
"d3036e36b330ad6caab68fa31c12c21f80c9b8cc7822416343a5100f09d6b640",
"s390x-unknown-linux-gnu-0.9.22":
"aff367a5c6ffb87b9cebbda4372464ca6aff69a53c81a94f1d78541be9677b2d",
"x86_64-apple-darwin-0.9.22":
"c0057ad78b475f343739b1bbe223361c1054524c9edf310ee1dc85a050207f86",
"x86_64-pc-windows-msvc-0.9.22":
"93a0a244f26eec208d8ea8077e3de743d9687ad76c190342722f1f57fa629457",
"x86_64-unknown-linux-gnu-0.9.22":
"e170aed70ac0225feee612e855d3a57ae73c61ffb22c7e52c3fd33b87c286508",
"x86_64-unknown-linux-musl-0.9.22":
"84d087a8e77a223d80578919894f3103f46ca7c263250c3e0478ce7c38850349",
"aarch64-apple-darwin-0.9.21":
"473977236ef8ac5937c80de08a3599cb6ed6021d0e015e10f88076767877a153",
"aarch64-pc-windows-msvc-0.9.21":
"54f66a44108b1b68583c9da0a515195d011189874ec9547710c032801726e042",
"aarch64-unknown-linux-gnu-0.9.21":
"416984484783a357170c43f98e7d2d203f1fb595d6b3b95131513c53e50986ef",
"aarch64-unknown-linux-musl-0.9.21":
"03a49fb609888032dbc3be9fd114b50fc9bce8b73b3df319746ae08d1fbdea83",
"arm-unknown-linux-musleabihf-0.9.21":
"5d84273d9e79aa1262e11d50b4b4e61c7b33bbbf47c7f7e271cb07f89ac479c1",
"armv7-unknown-linux-gnueabihf-0.9.21":
"74b2a73b3569cbba8c73470eb45dfba393401c834dd432fc8bd2039b40b1dde6",
"armv7-unknown-linux-musleabihf-0.9.21":
"fa3806603be42aad687bb97ff5939a32f5e1c21d565155299410ad445669ce11",
"i686-pc-windows-msvc-0.9.21":
"941e2b656cf9c94eac4b751933b24e5820247d938958c3d62d9d95d0e2409956",
"i686-unknown-linux-gnu-0.9.21":
"73fbd705cb4b5c071318afee896ba9984e3a14fcf7842435a93c43dc9ca0a12c",
"i686-unknown-linux-musl-0.9.21":
"c38f823354fff387758f6288ad184b104f47520b3cee7d53e92f3666b3466f55",
"powerpc64-unknown-linux-gnu-0.9.21":
"2cf68ea2ff75c4a627101bfe22064d6646a03cd7ddb939c933f3d8127b8d5982",
"powerpc64le-unknown-linux-gnu-0.9.21":
"3ede0329f67f5db37914b5dfd6014c414d27e1bf0153dab8d5cc2e066da034dc",
"riscv64gc-unknown-linux-gnu-0.9.21":
"3b7b070afd9c7be5a6364f081081cf9fec2160b53eba46cad27304b8b158e4ab",
"s390x-unknown-linux-gnu-0.9.21":
"34bd75d67a5819c9f796a78b1ec9ebd48021d87d2391b4cf282249c4d026f145",
"x86_64-apple-darwin-0.9.21":
"26390da48bd55e21ab62451a80ad240ef6df10d4c48ec199cbb34c18b4288983",
"x86_64-pc-windows-msvc-0.9.21":
"d27952e73183ef8f6ee8c2a50cf8b3f2e08e01b6a9279a00a85cb261ea8d8337",
"x86_64-unknown-linux-gnu-0.9.21":
"0a1ab27383c28ef1c041f85cbbc609d8e3752dfb4b238d2ad97b208a52232baf",
"x86_64-unknown-linux-musl-0.9.21":
"7abc29b3a06a99fb23564400fe884f5798a1786dc2ca05b6e0f70c53de748ab2",
"aarch64-apple-darwin-0.9.20":
"c3f4b03a5d526119d41fa8b8f255aa8053c49d787778df654895e3d174b1519a",
"aarch64-pc-windows-msvc-0.9.20":
"ddba8b1ca82df9b49745c93855c670490d776027269cf7de404d951919c96ea7",
"aarch64-unknown-linux-gnu-0.9.20":
"0451ecac1d0ed43d5870927df84c3d1dc93d72cf1933310acfadce5ad457c587",
"aarch64-unknown-linux-musl-0.9.20":
"d1b645d63c70da3f6f2368ea4dbc9dd5534b54be74ae32dee8941531c6874b6d",
"arm-unknown-linux-musleabihf-0.9.20":
"ddbaab7f1413f181bafc96c8b18af8e69372373798d2294d03d3935fd829c939",
"armv7-unknown-linux-gnueabihf-0.9.20":
"e1b2f5e4298878e6ac1137f744ba38b59ce68abd6a43878e66a1cac4dd7efd0e",
"armv7-unknown-linux-musleabihf-0.9.20":
"afc4a709ad83773bafa4ba83afa44bb101e44b817c5ad620cb9c54b62fe52e4e",
"i686-pc-windows-msvc-0.9.20":
"d7e50a3bc433bbb08e7890206bec0623627e6a911a6c10322c98721bde1a9cb0",
"i686-unknown-linux-gnu-0.9.20":
"aec778b1c44607416102139b6bb6a7f53a313fce8ad1033049b10ac90ed3c597",
"i686-unknown-linux-musl-0.9.20":
"92dd40f272b65f8301f0f9559fe55ac99b340caba93fe1952172e3485494cbba",
"powerpc64-unknown-linux-gnu-0.9.20":
"c2abda00a2b53cde9b6c8380ef9773749d341039771d7447df5647d935eb54c6",
"powerpc64le-unknown-linux-gnu-0.9.20":
"f40409d551a30081ada78cca7a1a260c02a7d16c912d73988d8e212324dea758",
"riscv64gc-unknown-linux-gnu-0.9.20":
"6dda223f877ff3eb3eba2fcf14abfd36280e5db1c0480addf5da5273ece087d6",
"s390x-unknown-linux-gnu-0.9.20":
"8ca14c1a9fe47ad2293a321f061c7278b32d7bc200d2692662790ab6ccd395c1",
"x86_64-apple-darwin-0.9.20":
"0059dc2986e7032c12b7039e1a66e570ab5c3a41598263c76e5a9c4e7da9f971",
"x86_64-pc-windows-msvc-0.9.20":
"be51ed9fcba5be4ac9c41a46aaf8af5cef86624fe27e2c645771b174069e049d",
"x86_64-unknown-linux-gnu-0.9.20":
"01ac5d872ab4cf6b11965c9df317f699882405f0319872fe3dbbb3adb045600b",
"x86_64-unknown-linux-musl-0.9.20":
"0de686dcc02e0b045980779e7330f2deb98e6cd9ece40d3341bd45c6733e682d",
"aarch64-apple-darwin-0.9.18":
"dc3bee4abbb3bac267a3985a23ea7617d19d41ff381dbaf560ba415ad65af68f",
"aarch64-pc-windows-msvc-0.9.18":
"fadb43ba13091f44e1786fc3967e65c7786d86192aa205d718307c649927cfc2",
"aarch64-unknown-linux-gnu-0.9.18":
"f8e23ec786b18660ade6b033b6191b7e9c283c872eeb8c4531d56a873decf160",
"aarch64-unknown-linux-musl-0.9.18":
"b710ceb9889276cbd7ce04e2ca06b5bd3e288da465bd38f7dd17955c4e703a65",
"arm-unknown-linux-musleabihf-0.9.18":
"2219049d28baaa0764e0315996e26c70ef548a0ba59add7f42358575ab04b410",
"armv7-unknown-linux-gnueabihf-0.9.18":
"dddf55144884f5d83b9f5795f0b16d023abedf615505962a6ebcaaef2cb62815",
"armv7-unknown-linux-musleabihf-0.9.18":
"265d49a8976a5956d3cab524e85e86df5397ab0daf6bd77f1494b0b9e1c00b9a",
"i686-pc-windows-msvc-0.9.18":
"52bd6fedef821a2412de73c31fdcf41c31b0a5c5886a416c3ba1a3d282ff02b8",
"i686-unknown-linux-gnu-0.9.18":
"6cc0437382adddd0439c874c41625539523725d551da9f9aecf7c0a3e86a1c77",
"i686-unknown-linux-musl-0.9.18":
"a727b054337ce453e98b80d6eccaa913cf542c155f3252503aff3e613735c640",
"powerpc64-unknown-linux-gnu-0.9.18":
"522154f752a90513cedcc621071893e46fb05d025ce8f0d4523514e8a87417d7",
"powerpc64le-unknown-linux-gnu-0.9.18":
"0660534d548800b17d2fc1dcdaf0f284e48ca3e34fff2b8b5c1797610e18fc0e",
"riscv64gc-unknown-linux-gnu-0.9.18":
"db6f5cbbc56a7212e61445a8cd1fcf880dc2906b4cac8f945320f0ab8eb9bf75",
"s390x-unknown-linux-gnu-0.9.18":
"bfa789548a345189b70d9069d9d7ef8f9c2236f0d10e2ae47a13549ffded5b84",
"x86_64-apple-darwin-0.9.18":
"f86836c637333c65bbc7902acc9c49888eef9fbd15dccbc1946b10e30b041073",
"x86_64-pc-windows-msvc-0.9.18":
"28cbe5d30907a774bfe27a517a39b494ec6f7d3816bda8bbf6f9645490449182",
"x86_64-unknown-linux-gnu-0.9.18":
"c2def3db178ade63933fa15ffc96e882c196ce53e06173dcee05b36c5f6f68f5",
"x86_64-unknown-linux-musl-0.9.18":
"a55ae2d0d53c8f6541bb4d6afc95857ff33a97de8f1d23e9d09acdcb865c4a00",
"aarch64-apple-darwin-0.9.17":
"a1e1464aa1d04d5e5fa700aa2f2e10397d1114e835dbd56be25ba65c9a31bd99",
"aarch64-pc-windows-msvc-0.9.17":
"28423a27ad1d82347c00411a6792567119b3c1cfe775d3312c0e08a6b489be5b",
"aarch64-unknown-linux-gnu-0.9.17":
"e9eba97b7169e47fd3c926e409f0b714820f0befc23b3ae062780586a793e4cc",
"aarch64-unknown-linux-musl-0.9.17":
"f6f48a301f8e855765af42ef50257af0cebc9c5439dfdcbc188142941aea45ca",
"arm-unknown-linux-musleabihf-0.9.17":
"4d80f3509b6351882a64c1dd08f72a80e2b27f055a996295ef1f935bc3efcdde",
"armv7-unknown-linux-gnueabihf-0.9.17":
"30a6c041429e2176062573f33c5c44307cb756264224bcb005723a6e18cff34c",
"armv7-unknown-linux-musleabihf-0.9.17":
"6b034dc63735c2a4541430cbece688e28bce51a09e2ad1ea2c1646a6b24cf1c3",
"i686-pc-windows-msvc-0.9.17":
"6e93737710e31bf73fcc3b4b6da616bd341e9c6baf1162ddc1e7f65884063f50",
"i686-unknown-linux-gnu-0.9.17":
"d2426a6d10bedd83524599bb0fbe0ba22e681ed45e892b4fd29086b424daf02a",
"i686-unknown-linux-musl-0.9.17":
"988c7702a2e88092b30f16fb7f8c18284a8062044cf57e6abd1dfeae82aa6377",
"powerpc64-unknown-linux-gnu-0.9.17":
"5ad301d9fa15e0791ef96abd83f0ed97e7ac1191b4b7578caaad3151633fb17c",
"powerpc64le-unknown-linux-gnu-0.9.17":
"4958185c5febf22f1c4c84944334cb0d9262c2c2c93faf30c1e0abd26f9d94fa",
"riscv64gc-unknown-linux-gnu-0.9.17":
"feed7cc7b5fc8a99e683ee1761cf99e3da12b60a2a413b7b87a0447726a66369",
"s390x-unknown-linux-gnu-0.9.17":
"a297518913a0f0e4af1bce434440ca9d415728aaf828c7def0e913aa5c46da8f",
"x86_64-apple-darwin-0.9.17":
"249e7fb18d45c06ba283c48f0a8e586ecc5fbb9e8dad0923c4169a7c4db815b2",
"x86_64-pc-windows-msvc-0.9.17":
"ebc76197bf3e1a58f9dac6f70f49b0ebd3e6907ab35289ce228bce5ba8a3f201",
"x86_64-unknown-linux-gnu-0.9.17":
"0114d54f9aafd07516cf1cadfe72afa970f5fd293fbe82dd924b8a7b42c984d8",
"x86_64-unknown-linux-musl-0.9.17":
"ab616c1851e7b1ed377a9ff3997dcee184bea7eda0b20bc8607abba6c469cbad",
"aarch64-apple-darwin-0.9.16": "aarch64-apple-darwin-0.9.16":
"db6d7fb299c35dc9bbbeb89cfa9aa55a9584f637d370c0a4c62a50df9c9294a7", "db6d7fb299c35dc9bbbeb89cfa9aa55a9584f637d370c0a4c62a50df9c9294a7",
"aarch64-pc-windows-msvc-0.9.16": "aarch64-pc-windows-msvc-0.9.16":

View File

@@ -1,13 +1,9 @@
import { promises as fs } from "node:fs"; import { promises as fs } from "node:fs";
import * as tc from "@actions/tool-cache";
export interface ChecksumEntry { import { KNOWN_CHECKSUMS } from "./known-checksums";
key: string;
checksum: string;
}
export async function updateChecksums( export async function updateChecksums(
filePath: string, filePath: string,
checksumEntries: ChecksumEntry[], downloadUrls: string[],
): Promise<void> { ): Promise<void> {
await fs.rm(filePath); await fs.rm(filePath);
await fs.appendFile( await fs.appendFile(
@@ -15,12 +11,49 @@ export async function updateChecksums(
"// AUTOGENERATED_DO_NOT_EDIT\nexport const KNOWN_CHECKSUMS: { [key: string]: string } = {\n", "// AUTOGENERATED_DO_NOT_EDIT\nexport const KNOWN_CHECKSUMS: { [key: string]: string } = {\n",
); );
let firstLine = true; let firstLine = true;
for (const entry of checksumEntries) { for (const downloadUrl of downloadUrls) {
const key = getKey(downloadUrl);
if (key === undefined) {
continue;
}
const checksum = await getOrDownloadChecksum(key, downloadUrl);
if (!firstLine) { if (!firstLine) {
await fs.appendFile(filePath, ",\n"); await fs.appendFile(filePath, ",\n");
} }
await fs.appendFile(filePath, ` "${entry.key}":\n "${entry.checksum}"`); await fs.appendFile(filePath, ` "${key}":\n "${checksum}"`);
firstLine = false; firstLine = false;
} }
await fs.appendFile(filePath, ",\n};\n"); await fs.appendFile(filePath, ",\n};\n");
} }
function getKey(downloadUrl: string): string | undefined {
// https://github.com/astral-sh/uv/releases/download/0.3.2/uv-aarch64-apple-darwin.tar.gz.sha256
const parts = downloadUrl.split("/");
const fileName = parts[parts.length - 1];
if (fileName.startsWith("source")) {
return undefined;
}
const name = fileName.split(".")[0].split("uv-")[1];
const version = parts[parts.length - 2];
return `${name}-${version}`;
}
async function getOrDownloadChecksum(
key: string,
downloadUrl: string,
): Promise<string> {
let checksum = "";
if (key in KNOWN_CHECKSUMS) {
checksum = KNOWN_CHECKSUMS[key];
} else {
const content = await downloadAssetContent(downloadUrl);
checksum = content.split(" ")[0].trim();
}
return checksum;
}
async function downloadAssetContent(downloadUrl: string): Promise<string> {
const downloadPath = await tc.downloadTool(downloadUrl);
const content = await fs.readFile(downloadPath, "utf8");
return content;
}

View File

@@ -2,20 +2,20 @@ import { promises as fs } from "node:fs";
import * as path from "node:path"; import * as path from "node:path";
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as tc from "@actions/tool-cache"; import * as tc from "@actions/tool-cache";
import type { Endpoints } from "@octokit/types";
import * as pep440 from "@renovatebot/pep440"; import * as pep440 from "@renovatebot/pep440";
import * as semver from "semver"; import * as semver from "semver";
import { OWNER, REPO, TOOL_CACHE_NAME } from "../utils/constants"; import { OWNER, REPO, TOOL_CACHE_NAME } from "../utils/constants";
import { Octokit } from "../utils/octokit";
import type { Architecture, Platform } from "../utils/platforms"; import type { Architecture, Platform } from "../utils/platforms";
import { validateChecksum } from "./checksum/checksum"; import { validateChecksum } from "./checksum/checksum";
import { import {
getDownloadUrl,
getLatestKnownVersion as getLatestVersionInManifest, getLatestKnownVersion as getLatestVersionInManifest,
getDownloadUrl as getManifestDownloadUrl,
} from "./version-manifest"; } from "./version-manifest";
import {
getAllVersions, type Release =
getArtifact, Endpoints["GET /repos/{owner}/{repo}/releases"]["response"]["data"][number];
getLatestVersion as getLatestVersionFromNdjson,
} from "./versions-client";
export function tryGetFromToolCache( export function tryGetFromToolCache(
arch: Architecture, arch: Architecture,
@@ -32,7 +32,7 @@ export function tryGetFromToolCache(
return { installedPath, version: resolvedVersion }; return { installedPath, version: resolvedVersion };
} }
export async function downloadVersionFromNdjson( export async function downloadVersionFromGithub(
platform: Platform, platform: Platform,
arch: Architecture, arch: Architecture,
version: string, version: string,
@@ -41,14 +41,7 @@ export async function downloadVersionFromNdjson(
): Promise<{ version: string; cachedToolDir: string }> { ): Promise<{ version: string; cachedToolDir: string }> {
const artifact = `uv-${arch}-${platform}`; const artifact = `uv-${arch}-${platform}`;
const extension = getExtension(platform); const extension = getExtension(platform);
const downloadUrl = `https://github.com/${OWNER}/${REPO}/releases/download/${version}/${artifact}${extension}`;
// Get artifact info from NDJSON (includes URL and checksum)
const artifactInfo = await getArtifact(version, arch, platform);
const downloadUrl =
artifactInfo?.url ??
`https://github.com/${OWNER}/${REPO}/releases/download/${version}/${artifact}${extension}`;
return await downloadVersion( return await downloadVersion(
downloadUrl, downloadUrl,
artifact, artifact,
@@ -57,30 +50,35 @@ export async function downloadVersionFromNdjson(
version, version,
checkSum, checkSum,
githubToken, githubToken,
artifactInfo?.sha256,
); );
} }
export async function downloadVersionFromManifest( export async function downloadVersionFromManifest(
manifestUrl: string, manifestUrl: string | undefined,
platform: Platform, platform: Platform,
arch: Architecture, arch: Architecture,
version: string, version: string,
checkSum: string | undefined, checkSum: string | undefined,
githubToken: string, githubToken: string,
): Promise<{ version: string; cachedToolDir: string }> { ): Promise<{ version: string; cachedToolDir: string }> {
const downloadUrl = await getManifestDownloadUrl( const downloadUrl = await getDownloadUrl(
manifestUrl, manifestUrl,
version, version,
arch, arch,
platform, platform,
); );
if (!downloadUrl) { if (!downloadUrl) {
throw new Error( core.info(
`manifest-file does not contain version ${version}, arch ${arch}, platform ${platform}.`, `manifest-file does not contain version ${version}, arch ${arch}, platform ${platform}. Falling back to GitHub releases.`,
);
return await downloadVersionFromGithub(
platform,
arch,
version,
checkSum,
githubToken,
); );
} }
return await downloadVersion( return await downloadVersion(
downloadUrl, downloadUrl,
`uv-${arch}-${platform}`, `uv-${arch}-${platform}`,
@@ -89,7 +87,6 @@ export async function downloadVersionFromManifest(
version, version,
checkSum, checkSum,
githubToken, githubToken,
undefined, // No NDJSON checksum for manifest downloads
); );
} }
@@ -101,7 +98,6 @@ async function downloadVersion(
version: string, version: string,
checkSum: string | undefined, checkSum: string | undefined,
githubToken: string, githubToken: string,
ndjsonChecksum?: string,
): Promise<{ version: string; cachedToolDir: string }> { ): Promise<{ version: string; cachedToolDir: string }> {
core.info(`Downloading uv from "${downloadUrl}" ...`); core.info(`Downloading uv from "${downloadUrl}" ...`);
const downloadPath = await tc.downloadTool( const downloadPath = await tc.downloadTool(
@@ -109,14 +105,7 @@ async function downloadVersion(
undefined, undefined,
githubToken, githubToken,
); );
await validateChecksum( await validateChecksum(checkSum, downloadPath, arch, platform, version);
checkSum,
downloadPath,
arch,
platform,
version,
ndjsonChecksum,
);
let uvDir: string; let uvDir: string;
if (platform === "pc-windows-msvc") { if (platform === "pc-windows-msvc") {
@@ -154,6 +143,7 @@ function getExtension(platform: Platform): string {
export async function resolveVersion( export async function resolveVersion(
versionInput: string, versionInput: string,
manifestFile: string | undefined, manifestFile: string | undefined,
githubToken: string,
resolutionStrategy: "highest" | "lowest" = "highest", resolutionStrategy: "highest" | "lowest" = "highest",
): Promise<string> { ): Promise<string> {
core.debug(`Resolving version: ${versionInput}`); core.debug(`Resolving version: ${versionInput}`);
@@ -173,7 +163,7 @@ export async function resolveVersion(
} else { } else {
version = version =
versionInput === "latest" || resolveVersionSpecifierToLatest versionInput === "latest" || resolveVersionSpecifierToLatest
? await getLatestVersionFromNdjson() ? await getLatestVersion(githubToken)
: versionInput; : versionInput;
} }
if (tc.isExplicitVersion(version)) { if (tc.isExplicitVersion(version)) {
@@ -185,7 +175,7 @@ export async function resolveVersion(
} }
return version; return version;
} }
const availableVersions = await getAvailableVersions(); const availableVersions = await getAvailableVersions(githubToken);
core.debug(`Available versions: ${availableVersions}`); core.debug(`Available versions: ${availableVersions}`);
const resolvedVersion = const resolvedVersion =
resolutionStrategy === "lowest" resolutionStrategy === "lowest"
@@ -197,9 +187,79 @@ export async function resolveVersion(
return resolvedVersion; return resolvedVersion;
} }
async function getAvailableVersions(): Promise<string[]> { async function getAvailableVersions(githubToken: string): Promise<string[]> {
core.info("Getting available versions from NDJSON..."); core.info("Getting available versions from GitHub API...");
return await getAllVersions(); try {
const octokit = new Octokit({
auth: githubToken,
});
return await getReleaseTagNames(octokit);
} catch (err) {
if ((err as Error).message.includes("Bad credentials")) {
core.info(
"No (valid) GitHub token provided. Falling back to anonymous. Requests might be rate limited.",
);
const octokit = new Octokit();
return await getReleaseTagNames(octokit);
}
throw err;
}
}
async function getReleaseTagNames(octokit: Octokit): Promise<string[]> {
const response: Release[] = await octokit.paginate(
octokit.rest.repos.listReleases,
{
owner: OWNER,
repo: REPO,
},
);
const releaseTagNames = response.map((release) => release.tag_name);
if (releaseTagNames.length === 0) {
throw Error(
"Github API request failed while getting releases. Check the GitHub status page for outages. Try again later.",
);
}
return releaseTagNames;
}
async function getLatestVersion(githubToken: string) {
core.info("Getting latest version from GitHub API...");
const octokit = new Octokit({
auth: githubToken,
});
let latestRelease: { tag_name: string } | undefined;
try {
latestRelease = await getLatestRelease(octokit);
} catch (err) {
if ((err as Error).message.includes("Bad credentials")) {
core.info(
"No (valid) GitHub token provided. Falling back to anonymous. Requests might be rate limited.",
);
const octokit = new Octokit();
latestRelease = await getLatestRelease(octokit);
} else {
core.error(
"Github API request failed while getting latest release. Check the GitHub status page for outages. Try again later.",
);
throw err;
}
}
if (!latestRelease) {
throw new Error("Could not determine latest release.");
}
core.debug(`Latest version: ${latestRelease.tag_name}`);
return latestRelease.tag_name;
}
async function getLatestRelease(octokit: Octokit) {
const { data: latestRelease } = await octokit.rest.repos.getLatestRelease({
owner: OWNER,
repo: REPO,
});
return latestRelease;
} }
function maxSatisfying( function maxSatisfying(

View File

@@ -1,113 +0,0 @@
import * as core from "@actions/core";
import { VERSIONS_NDJSON_URL } from "../utils/constants";
import { fetch } from "../utils/fetch";
export interface NdjsonArtifact {
platform: string;
variant: string;
url: string;
archive_format: string;
sha256: string;
}
export interface NdjsonVersion {
version: string;
artifacts: NdjsonArtifact[];
}
let cachedVersionData: NdjsonVersion[] | null = null;
export async function fetchVersionData(): Promise<NdjsonVersion[]> {
if (cachedVersionData !== null) {
core.debug("Using cached NDJSON version data");
return cachedVersionData;
}
core.info(`Fetching version data from ${VERSIONS_NDJSON_URL}...`);
const response = await fetch(VERSIONS_NDJSON_URL, {});
if (!response.ok) {
throw new Error(
`Failed to fetch version data: ${response.status} ${response.statusText}`,
);
}
const body = await response.text();
const versions: NdjsonVersion[] = [];
for (const line of body.split("\n")) {
const trimmed = line.trim();
if (trimmed === "") {
continue;
}
try {
const version = JSON.parse(trimmed) as NdjsonVersion;
versions.push(version);
} catch {
core.debug(`Failed to parse NDJSON line: ${trimmed}`);
}
}
if (versions.length === 0) {
throw new Error("No version data found in NDJSON file");
}
cachedVersionData = versions;
return versions;
}
export async function getLatestVersion(): Promise<string> {
const versions = await fetchVersionData();
// The NDJSON file lists versions in order, newest first
const latestVersion = versions[0]?.version;
if (!latestVersion) {
throw new Error("No versions found in NDJSON data");
}
core.debug(`Latest version from NDJSON: ${latestVersion}`);
return latestVersion;
}
export async function getAllVersions(): Promise<string[]> {
const versions = await fetchVersionData();
return versions.map((v) => v.version);
}
export interface ArtifactResult {
url: string;
sha256: string;
}
export async function getArtifact(
version: string,
arch: string,
platform: string,
): Promise<ArtifactResult | undefined> {
const versions = await fetchVersionData();
const versionData = versions.find((v) => v.version === version);
if (!versionData) {
core.debug(`Version ${version} not found in NDJSON data`);
return undefined;
}
// The NDJSON artifact platform format is like "x86_64-apple-darwin"
// We need to match against arch-platform
const targetPlatform = `${arch}-${platform}`;
const artifact = versionData.artifacts.find(
(a) => a.platform === targetPlatform,
);
if (!artifact) {
core.debug(
`Artifact for ${targetPlatform} not found in version ${version}. Available platforms: ${versionData.artifacts.map((a) => a.platform).join(", ")}`,
);
return undefined;
}
return {
sha256: artifact.sha256,
url: artifact.url,
};
}
export function clearCache(): void {
cachedVersionData = null;
}

View File

@@ -6,7 +6,6 @@ import * as pep440 from "@renovatebot/pep440";
import { import {
STATE_CACHE_KEY, STATE_CACHE_KEY,
STATE_CACHE_MATCHED_KEY, STATE_CACHE_MATCHED_KEY,
STATE_PYTHON_CACHE_MATCHED_KEY,
} from "./cache/restore-cache"; } from "./cache/restore-cache";
import { STATE_UV_PATH, STATE_UV_VERSION } from "./utils/constants"; import { STATE_UV_PATH, STATE_UV_VERSION } from "./utils/constants";
import { import {
@@ -53,30 +52,63 @@ async function saveCache(): Promise<void> {
} }
if (matchedKey === cacheKey) { if (matchedKey === cacheKey) {
core.info(`Cache hit occurred on key ${cacheKey}, not saving cache.`); core.info(`Cache hit occurred on key ${cacheKey}, not saving cache.`);
} else { return;
if (shouldPruneCache) { }
await pruneCache();
}
const actualCachePath = getUvCachePath(); if (shouldPruneCache) {
await saveCacheToKey( await pruneCache();
cacheKey, }
actualCachePath,
STATE_CACHE_MATCHED_KEY, if (cacheLocalPath === undefined) {
"uv cache", throw new Error(
"cache-local-path is not set. Cannot save cache without a valid cache path.",
);
}
let actualCachePath = cacheLocalPath.path;
if (
process.env.UV_CACHE_DIR &&
process.env.UV_CACHE_DIR !== cacheLocalPath.path
) {
core.warning(
`The environment variable UV_CACHE_DIR has been changed to "${process.env.UV_CACHE_DIR}", by an action or step running after astral-sh/setup-uv. This can lead to unexpected behavior. If you expected this to happen set the cache-local-path input to "${process.env.UV_CACHE_DIR}" instead of "${cacheLocalPath.path}".`,
);
actualCachePath = process.env.UV_CACHE_DIR;
}
core.info(`Saving cache path: ${actualCachePath}`);
if (!fs.existsSync(actualCachePath) && !ignoreNothingToCache) {
throw new Error(
`Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`, `Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`,
); );
} }
const cachePaths = [actualCachePath];
if (cachePython) { if (cachePython) {
const pythonCacheKey = `${cacheKey}-python`; core.info(`Including Python cache path: ${pythonDir}`);
await saveCacheToKey( if (!fs.existsSync(pythonDir) && !ignoreNothingToCache) {
pythonCacheKey, throw new Error(
pythonDir, `Python cache path ${pythonDir} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`,
STATE_PYTHON_CACHE_MATCHED_KEY, );
"Python cache", }
`Python cache path ${pythonDir} does not exist on disk. This likely indicates that there are no Python installations to cache. Consider disabling the cache input if it is not needed.`, cachePaths.push(pythonDir);
); }
core.info(`Final cache paths: ${cachePaths.join(", ")}`);
try {
await cache.saveCache(cachePaths, cacheKey);
core.info(`cache saved with the key: ${cacheKey}`);
} catch (e) {
if (
e instanceof Error &&
e.message ===
"Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved."
) {
core.info(
"No cacheable paths were found. Ignoring because ignore-nothing-to-save is enabled.",
);
} else {
throw e;
}
} }
} }
@@ -96,61 +128,4 @@ async function pruneCache(): Promise<void> {
await exec.exec(uvPath, execArgs, options); await exec.exec(uvPath, execArgs, options);
} }
function getUvCachePath(): string {
if (cacheLocalPath === undefined) {
throw new Error(
"cache-local-path is not set. Cannot save cache without a valid cache path.",
);
}
if (
process.env.UV_CACHE_DIR &&
process.env.UV_CACHE_DIR !== cacheLocalPath.path
) {
core.warning(
`The environment variable UV_CACHE_DIR has been changed to "${process.env.UV_CACHE_DIR}", by an action or step running after astral-sh/setup-uv. This can lead to unexpected behavior. If you expected this to happen set the cache-local-path input to "${process.env.UV_CACHE_DIR}" instead of "${cacheLocalPath.path}".`,
);
return process.env.UV_CACHE_DIR;
}
return cacheLocalPath.path;
}
async function saveCacheToKey(
cacheKey: string,
cachePath: string,
stateKey: string,
cacheName: string,
pathNotExistErrorMessage: string,
): Promise<void> {
const matchedKey = core.getState(stateKey);
if (matchedKey === cacheKey) {
core.info(
`${cacheName} hit occurred on key ${cacheKey}, not saving cache.`,
);
return;
}
core.info(`Including ${cacheName} path: ${cachePath}`);
if (!fs.existsSync(cachePath) && !ignoreNothingToCache) {
throw new Error(pathNotExistErrorMessage);
}
try {
await cache.saveCache([cachePath], cacheKey);
core.info(`${cacheName} saved with key: ${cacheKey}`);
} catch (e) {
if (
e instanceof Error &&
e.message ===
"Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved."
) {
core.info(
`No cacheable ${cacheName} paths were found. Ignoring because ignore-nothing-to-save is enabled.`,
);
} else {
throw e;
}
}
}
run(); run();

View File

@@ -5,7 +5,6 @@ import * as exec from "@actions/exec";
import { restoreCache } from "./cache/restore-cache"; import { restoreCache } from "./cache/restore-cache";
import { import {
downloadVersionFromManifest, downloadVersionFromManifest,
downloadVersionFromNdjson,
resolveVersion, resolveVersion,
tryGetFromToolCache, tryGetFromToolCache,
} from "./download/download-version"; } from "./download/download-version";
@@ -37,37 +36,6 @@ import {
} from "./utils/platforms"; } from "./utils/platforms";
import { getUvVersionFromFile } from "./version/resolve"; import { getUvVersionFromFile } from "./version/resolve";
async function getPythonVersion(): Promise<string> {
if (pythonVersion !== "") {
return pythonVersion;
}
let output = "";
const options: exec.ExecOptions = {
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
},
},
silent: !core.isDebug(),
};
try {
const execArgs = ["python", "find", "--directory", workingDirectory];
await exec.exec("uv", execArgs, options);
const pythonPath = output.trim();
output = "";
await exec.exec(pythonPath, ["--version"], options);
// output is like "Python 3.8.10"
return output.split(" ")[1].trim();
} catch (error) {
const err = error as Error;
core.debug(`Failed to get python version from uv. Error: ${err.message}`);
return "unknown";
}
}
async function run(): Promise<void> { async function run(): Promise<void> {
detectEmptyWorkdir(); detectEmptyWorkdir();
const platform = await getPlatform(); const platform = await getPlatform();
@@ -95,11 +63,8 @@ async function run(): Promise<void> {
core.saveState(STATE_UV_VERSION, setupResult.version); core.saveState(STATE_UV_VERSION, setupResult.version);
core.info(`Successfully installed uv version ${setupResult.version}`); core.info(`Successfully installed uv version ${setupResult.version}`);
const pythonVersion = await getPythonVersion();
core.setOutput("python-version", pythonVersion);
if (enableCache) { if (enableCache) {
await restoreCache(pythonVersion); await restoreCache();
} }
// https://github.com/nodejs/node/issues/56645#issuecomment-3077594952 // https://github.com/nodejs/node/issues/56645#issuecomment-3077594952
await new Promise((resolve) => setTimeout(resolve, 50)); await new Promise((resolve) => setTimeout(resolve, 50));
@@ -139,23 +104,14 @@ async function setupUv(
}; };
} }
// Use the same source for download as we used for version resolution const downloadVersionResult = await downloadVersionFromManifest(
const downloadVersionResult = manifestFile manifestFile,
? await downloadVersionFromManifest( platform,
manifestFile, arch,
platform, resolvedVersion,
arch, checkSum,
resolvedVersion, githubToken,
checkSum, );
githubToken,
)
: await downloadVersionFromNdjson(
platform,
arch,
resolvedVersion,
checkSum,
githubToken,
);
return { return {
uvDir: downloadVersionResult.cachedToolDir, uvDir: downloadVersionResult.cachedToolDir,
@@ -167,7 +123,12 @@ async function determineVersion(
manifestFile: string | undefined, manifestFile: string | undefined,
): Promise<string> { ): Promise<string> {
if (versionInput !== "") { if (versionInput !== "") {
return await resolveVersion(versionInput, manifestFile, resolutionStrategy); return await resolveVersion(
versionInput,
manifestFile,
githubToken,
resolutionStrategy,
);
} }
if (versionFileInput !== "") { if (versionFileInput !== "") {
const versionFromFile = getUvVersionFromFile(versionFileInput); const versionFromFile = getUvVersionFromFile(versionFileInput);
@@ -179,6 +140,7 @@ async function determineVersion(
return await resolveVersion( return await resolveVersion(
versionFromFile, versionFromFile,
manifestFile, manifestFile,
githubToken,
resolutionStrategy, resolutionStrategy,
); );
} }
@@ -196,6 +158,7 @@ async function determineVersion(
return await resolveVersion( return await resolveVersion(
versionFromUvToml || versionFromPyproject || "latest", versionFromUvToml || versionFromPyproject || "latest",
manifestFile, manifestFile,
githubToken,
resolutionStrategy, resolutionStrategy,
); );
} }

View File

@@ -1,116 +1,63 @@
import { promises as fs } from "node:fs";
import * as core from "@actions/core"; import * as core from "@actions/core";
import type { Endpoints } from "@octokit/types";
import * as semver from "semver"; import * as semver from "semver";
import { updateChecksums } from "./download/checksum/update-known-checksums"; import { updateChecksums } from "./download/checksum/update-known-checksums";
import { getLatestKnownVersion } from "./download/version-manifest";
import { import {
fetchVersionData, getLatestKnownVersion,
getLatestVersion, updateVersionManifest,
type NdjsonVersion, } from "./download/version-manifest";
} from "./download/versions-client"; import { OWNER, REPO } from "./utils/constants";
import { Octokit } from "./utils/octokit";
interface ChecksumEntry { type Release =
key: string; Endpoints["GET /repos/{owner}/{repo}/releases"]["response"]["data"][number];
checksum: string;
}
interface ArtifactEntry {
version: string;
artifactName: string;
arch: string;
platform: string;
downloadUrl: string;
}
function extractChecksumsFromNdjson(
versions: NdjsonVersion[],
): ChecksumEntry[] {
const checksums: ChecksumEntry[] = [];
for (const version of versions) {
for (const artifact of version.artifacts) {
// The platform field contains the target triple like "x86_64-apple-darwin"
const key = `${artifact.platform}-${version.version}`;
checksums.push({
checksum: artifact.sha256,
key,
});
}
}
return checksums;
}
function extractArtifactsFromNdjson(
versions: NdjsonVersion[],
): ArtifactEntry[] {
const artifacts: ArtifactEntry[] = [];
for (const version of versions) {
for (const artifact of version.artifacts) {
// The platform field contains the target triple like "x86_64-apple-darwin"
// Split into arch and platform (e.g., "x86_64-apple-darwin" -> ["x86_64", "apple-darwin"])
const parts = artifact.platform.split("-");
const arch = parts[0];
const platform = parts.slice(1).join("-");
// Construct artifact name from platform and archive format
const artifactName = `uv-${artifact.platform}.${artifact.archive_format}`;
artifacts.push({
arch,
artifactName,
downloadUrl: artifact.url,
platform,
version: version.version,
});
}
}
return artifacts;
}
async function run(): Promise<void> { async function run(): Promise<void> {
const checksumFilePath = process.argv.slice(2)[0]; const checksumFilePath = process.argv.slice(2)[0];
const versionsManifestFile = process.argv.slice(2)[1]; const versionsManifestFile = process.argv.slice(2)[1];
const githubToken = process.argv.slice(2)[2];
const octokit = new Octokit({
auth: githubToken,
});
const { data: latestRelease } = await octokit.rest.repos.getLatestRelease({
owner: OWNER,
repo: REPO,
});
const latestVersion = await getLatestVersion();
const latestKnownVersion = await getLatestKnownVersion(undefined); const latestKnownVersion = await getLatestKnownVersion(undefined);
if (semver.lte(latestVersion, latestKnownVersion)) { if (semver.lte(latestRelease.tag_name, latestKnownVersion)) {
core.info( core.info(
`Latest release (${latestVersion}) is not newer than the latest known version (${latestKnownVersion}). Skipping update.`, `Latest release (${latestRelease.tag_name}) is not newer than the latest known version (${latestKnownVersion}). Skipping update.`,
); );
return; return;
} }
const versions = await fetchVersionData(); const releases: Release[] = await octokit.paginate(
octokit.rest.repos.listReleases,
{
owner: OWNER,
repo: REPO,
},
);
const checksumDownloadUrls: string[] = releases.flatMap((release) =>
release.assets
.filter((asset) => asset.name.endsWith(".sha256"))
.map((asset) => asset.browser_download_url),
);
await updateChecksums(checksumFilePath, checksumDownloadUrls);
// Extract checksums from NDJSON const artifactDownloadUrls: string[] = releases.flatMap((release) =>
const checksumEntries = extractChecksumsFromNdjson(versions); release.assets
await updateChecksums(checksumFilePath, checksumEntries); .filter((asset) => !asset.name.endsWith(".sha256"))
.map((asset) => asset.browser_download_url),
);
// Extract artifact URLs for version manifest await updateVersionManifest(versionsManifestFile, artifactDownloadUrls);
const artifactEntries = extractArtifactsFromNdjson(versions);
await updateVersionManifestFromEntries(versionsManifestFile, artifactEntries);
core.setOutput("latest-version", latestVersion); core.setOutput("latest-version", latestRelease.tag_name);
}
async function updateVersionManifestFromEntries(
filePath: string,
entries: ArtifactEntry[],
): Promise<void> {
const manifest = entries.map((entry) => ({
arch: entry.arch,
artifactName: entry.artifactName,
downloadUrl: entry.downloadUrl,
platform: entry.platform,
version: entry.version,
}));
core.debug(`Updating manifest-file: ${JSON.stringify(manifest)}`);
await fs.writeFile(filePath, JSON.stringify(manifest));
} }
run(); run();

View File

@@ -3,5 +3,3 @@ export const OWNER = "astral-sh";
export const TOOL_CACHE_NAME = "uv"; export const TOOL_CACHE_NAME = "uv";
export const STATE_UV_PATH = "uv-path"; export const STATE_UV_PATH = "uv-path";
export const STATE_UV_VERSION = "uv-version"; export const STATE_UV_VERSION = "uv-version";
export const VERSIONS_NDJSON_URL =
"https://raw.githubusercontent.com/astral-sh/versions/main/v1/uv.ndjson";

View File

@@ -155,7 +155,7 @@ function getCacheDirFromConfig(): string | undefined {
export function getUvPythonDir(): string { export function getUvPythonDir(): string {
if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) { if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) {
core.info( core.info(
`UV_PYTHON_INSTALL_DIR is already set to ${process.env.UV_PYTHON_INSTALL_DIR}`, `UV_PYTHON_INSTALL_DIR is already set to ${process.env.UV_PYTHON_INSTALL_DIR}`,
); );
return process.env.UV_PYTHON_INSTALL_DIR; return process.env.UV_PYTHON_INSTALL_DIR;
} }

34
src/utils/octokit.ts Normal file
View File

@@ -0,0 +1,34 @@
import type { OctokitOptions } from "@octokit/core";
import { Octokit as Core } from "@octokit/core";
import {
type PaginateInterface,
paginateRest,
} from "@octokit/plugin-paginate-rest";
import { legacyRestEndpointMethods } from "@octokit/plugin-rest-endpoint-methods";
import { fetch as customFetch } from "./fetch";
export type { RestEndpointMethodTypes } from "@octokit/plugin-rest-endpoint-methods";
const DEFAULTS = {
baseUrl: "https://api.github.com",
userAgent: "setup-uv",
};
const OctokitWithPlugins = Core.plugin(paginateRest, legacyRestEndpointMethods);
export const Octokit = OctokitWithPlugins.defaults(function buildDefaults(
options: OctokitOptions,
): OctokitOptions {
return {
...DEFAULTS,
...options,
request: {
fetch: customFetch,
...options.request,
},
};
});
export type Octokit = InstanceType<typeof OctokitWithPlugins> & {
paginate: PaginateInterface;
};

View File

@@ -1,5 +1,3 @@
import fs from "node:fs";
import os from "node:os";
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as exec from "@actions/exec"; import * as exec from "@actions/exec";
export type Platform = export type Platform =
@@ -76,71 +74,3 @@ async function isMuslOs(): Promise<boolean> {
return false; return false;
} }
} }
/**
* Returns OS name and version for cache key differentiation.
* Examples: "ubuntu-22.04", "macos-14", "windows-2022"
* Throws if OS detection fails.
*/
export function getOSNameVersion(): string {
const platform = process.platform;
if (platform === "linux") {
return getLinuxOSNameVersion();
}
if (platform === "darwin") {
return getMacOSNameVersion();
}
if (platform === "win32") {
return getWindowsNameVersion();
}
throw new Error(`Unsupported platform: ${platform}`);
}
function getLinuxOSNameVersion(): string {
const files = ["/etc/os-release", "/usr/lib/os-release"];
for (const file of files) {
try {
const content = fs.readFileSync(file, "utf8");
const id = parseOsReleaseValue(content, "ID");
const versionId = parseOsReleaseValue(content, "VERSION_ID");
if (id && versionId) {
return `${id}-${versionId}`;
}
} catch {
// Try next file
}
}
throw new Error(
"Failed to determine Linux distribution. " +
"Could not read /etc/os-release or /usr/lib/os-release",
);
}
function parseOsReleaseValue(content: string, key: string): string | undefined {
const regex = new RegExp(`^${key}=["']?([^"'\\n]*)["']?$`, "m");
const match = content.match(regex);
return match?.[1];
}
function getMacOSNameVersion(): string {
const darwinVersion = Number.parseInt(os.release().split(".")[0], 10);
if (Number.isNaN(darwinVersion)) {
throw new Error(`Failed to parse macOS version from: ${os.release()}`);
}
const macosVersion = darwinVersion - 9;
return `macos-${macosVersion}`;
}
function getWindowsNameVersion(): string {
const version = os.version();
const match = version.match(/Windows(?: Server)? (\d+)/);
if (!match) {
throw new Error(`Failed to parse Windows version from: ${version}`);
}
return `windows-${match[1]}`;
}

File diff suppressed because it is too large Load Diff