Compare commits

..

No commits in common. "main" and "v4.5.0" have entirely different histories.
main ... v4.5.0

115 changed files with 35191 additions and 101323 deletions

View File

@ -1,6 +0,0 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!src/

View File

@ -1,51 +0,0 @@
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:eslint-plugin-jest/recommended',
'eslint-config-prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'eslint-plugin-node', 'eslint-plugin-jest'],
rules: {
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-ignore': 'allow-with-description'
}
],
'no-console': 'error',
'yoda': 'error',
'prefer-const': [
'error',
{
destructuring: 'all'
}
],
'no-control-regex': 'off',
'no-constant-condition': ['error', {checkLoops: false}],
'node/no-extraneous-import': 'error'
},
overrides: [
{
files: ['**/*{test,spec}.ts'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'jest/no-standalone-expect': 'off',
'jest/no-conditional-expect': 'off',
'no-console': 'off',
}
}
],
env: {
node: true,
es6: true,
'jest/globals': true
}
};

View File

@ -1,22 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: 'npm'
# Look for `package.json` and `lock` files in the `root` directory
directory: '/'
# Check the npm registry for updates every day (weekdays)
schedule:
interval: 'weekly'
# Enable version updates for GitHub Actions
- package-ecosystem: 'github-actions'
# Workflow files stored in the default location of `.github/workflows`
# You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.
directory: '/'
schedule:
interval: 'weekly'

View File

@ -13,5 +13,3 @@ jobs:
call-basic-validation: call-basic-validation:
name: Basic validation name: Basic validation
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
with:
node-version: '20.x'

View File

@ -15,5 +15,3 @@ jobs:
call-check-dist: call-check-dist:
name: Check dist/ name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
with:
node-version: '20.x'

View File

@ -1,164 +0,0 @@
name: e2e-cache freethread
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- main
- releases/*
paths-ignore:
- '**.md'
workflow_dispatch:
permissions:
contents: read
jobs:
python-pip-dependencies-caching:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-22.04,
ubuntu-24.04-arm,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: pip install numpy pandas requests
python-pipenv-dependencies-caching:
name: Test pipenv (Python ${{ matrix.python-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- uses: actions/checkout@v4
- name: Setup Python
id: cache-pipenv
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pipenv'
- name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies
run: pipenv install requests
python-poetry-dependencies-caching:
name: Test poetry (Python ${{ matrix.python-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-22.04,
ubuntu-24.04-arm,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: [3.13.0, 3.13.1, 3.13.2]
steps:
- uses: actions/checkout@v4
- name: Install poetry
run: pipx install poetry
- name: Init pyproject.toml
run: mv ./__tests__/data/pyproject.toml .
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
freethreaded: true
cache: 'poetry'
- name: Install dependencies
run: poetry install --no-root
python-pip-dependencies-caching-path:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-22.04,
ubuntu-24.04-arm,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: __tests__/data/requirements.txt
- name: Install dependencies
run: pip install numpy pandas requests
python-pipenv-dependencies-caching-path:
name: Test pipenv (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-22.04,
ubuntu-24.04-arm,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- uses: actions/checkout@v4
- name: Setup Python
id: cache-pipenv
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pipenv'
cache-dependency-path: '**/pipenv-requirements.txt'
- name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies
run: pipenv install requests

View File

@ -10,7 +10,6 @@ on:
- releases/* - releases/*
paths-ignore: paths-ignore:
- '**.md' - '**.md'
workflow_dispatch:
permissions: permissions:
contents: read contents: read
@ -21,32 +20,10 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[ python-version: ['3.9', 'pypy-3.7-v7.x']
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version:
[
'3.9',
'pypy-3.9-v7.x',
'3.10',
'pypy-3.10-v7.x',
'3.11',
'pypy-3.11-v7.x',
'3.12',
'3.13'
]
exclude:
- os: windows-latest
python-version: pypy-3.11-v7.x
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@ -61,56 +38,27 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[ python-version: ['3.9', 'pypy-3.9-v7.x']
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version:
['3.10', 'pypy-3.10-v7.x', '3.11', 'pypy-3.11-v7.x', '3.12', '3.13']
exclude:
- os: windows-latest
python-version: pypy-3.11-v7.x
- os: ubuntu-22.04
python-version: pypy-3.11-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.10-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.11-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.10-v7.x
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
id: cache-pipenv
uses: ./ uses: ./
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'pipenv' cache: 'pipenv'
- name: Install pipenv - name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Prepare environment - name: Install dependencies
shell: pwsh shell: pwsh
run: | run: |
mv ./__tests__/data/Pipfile.lock . mv ./__tests__/data/Pipfile.lock .
mv ./__tests__/data/Pipfile . mv ./__tests__/data/Pipfile .
mv ./__tests__/test-pipenv.py .
- name: Install dependencies
shell: pwsh
if: steps.cache-pipenv.outputs.cache-hit != 'true'
run: |
if ("${{ matrix.python-version }}" -Match "pypy") { if ("${{ matrix.python-version }}" -Match "pypy") {
pipenv install --python pypy # --keep-outdated pipenv install --keep-outdated --python pypy
} else { } else {
pipenv install --python ${{ matrix.python-version }} # --keep-outdated pipenv install --keep-outdated --python ${{ matrix.python-version }}
} }
- name: Run Python Script
run: pipenv run python test-pipenv.py
python-poetry-dependencies-caching: python-poetry-dependencies-caching:
name: Test poetry (Python ${{ matrix.python-version}}, ${{ matrix.os }}) name: Test poetry (Python ${{ matrix.python-version}}, ${{ matrix.os }})
@ -118,29 +66,10 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[ python-version: ['3.9', 'pypy-3.8']
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version:
[
'3.9',
'pypy-3.9-v7.x',
'3.10',
'pypy-3.10-v7.x',
'3.11',
'pypy-3.11-v7.x',
'3.12',
'3.13'
]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install poetry - name: Install poetry
run: pipx install poetry run: pipx install poetry
- name: Init pyproject.toml - name: Init pyproject.toml
@ -151,40 +80,18 @@ jobs:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'poetry' cache: 'poetry'
- name: Install dependencies - name: Install dependencies
run: poetry install --no-root run: poetry install
python-pip-dependencies-caching-path: python-pip-dependencies-caching-path:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path) name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[ python-version: ['3.9', 'pypy-3.7-v7.x']
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version:
[
'3.9',
'pypy-3.9-v7.x',
'3.10',
'pypy-3.10-v7.x',
'3.11',
'pypy-3.11-v7.x',
'3.12',
'3.13'
]
exclude:
- os: windows-latest
python-version: pypy-3.11-v7.x
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@ -195,36 +102,16 @@ jobs:
run: pip install numpy pandas requests run: pip install numpy pandas requests
python-pipenv-dependencies-caching-path: python-pipenv-dependencies-caching-path:
name: Test pipenv (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path) name: Test pipenv (Python ${{ matrix.python-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[ python-version: ['3.9', 'pypy-3.9-v7.x']
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version:
['3.10', 'pypy-3.10-v7.x', '3.11', 'pypy-3.11-v7.x', '3.12', '3.13']
exclude:
- os: windows-latest
python-version: pypy-3.11-v7.x
- os: ubuntu-22.04
python-version: pypy-3.11-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.10-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.11-v7.x
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
id: cache-pipenv
uses: ./ uses: ./
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
@ -232,20 +119,13 @@ jobs:
cache-dependency-path: '**/pipenv-requirements.txt' cache-dependency-path: '**/pipenv-requirements.txt'
- name: Install pipenv - name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Prepare environment - name: Install dependencies
shell: pwsh shell: pwsh
run: | run: |
mv ./__tests__/data/Pipfile.lock . mv ./__tests__/data/Pipfile.lock .
mv ./__tests__/data/Pipfile . mv ./__tests__/data/Pipfile .
mv ./__tests__/test-pipenv.py .
- name: Install dependencies
shell: pwsh
if: steps.cache-pipenv.outputs.cache-hit != 'true'
run: |
if ("${{ matrix.python-version }}" -Match "pypy") { if ("${{ matrix.python-version }}" -Match "pypy") {
pipenv install --python pypy # --keep-outdated pipenv install --keep-outdated --python pypy
} else { } else {
pipenv install --python ${{ matrix.python-version }} # --keep-outdated pipenv install --keep-outdated --python ${{ matrix.python-version }}
} }
- name: Run Python Script
run: pipenv run python test-pipenv.py

View File

@ -9,7 +9,6 @@ on:
pull_request: pull_request:
paths-ignore: paths-ignore:
- '**.md' - '**.md'
workflow_dispatch:
jobs: jobs:
test-setup-python: test-setup-python:
@ -17,79 +16,73 @@ jobs:
runs-on: ${{ matrix.operating-system }} runs-on: ${{ matrix.operating-system }}
strategy: strategy:
matrix: matrix:
operating-system: operating-system: [ubuntu-20.04, windows-latest]
[
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-latest,
ubuntu-24.04-arm,
macos-latest,
macos-13
]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Run with setup-python 3.9.13 - name: Run with setup-python 2.7
uses: ./ uses: ./
with: with:
python-version: 3.9.13 python-version: 2.7
- name: Verify 3.9.13 - name: Verify 2.7
run: python __tests__/verify-python.py 3.9.13 run: python __tests__/verify-python.py 2.7
- name: Run with setup-python 3.9.13 - name: Run with setup-python 3.5
uses: ./ uses: ./
with: with:
python-version: 3.10.11 python-version: 3.5
- name: Verify 3.10.11 - name: Verify 3.5
run: python __tests__/verify-python.py 3.10.11 run: python __tests__/verify-python.py 3.5
- name: Run with setup-python 3.11.9 - name: Run with setup-python 3.6
uses: ./ uses: ./
with: with:
python-version: 3.11.9 python-version: 3.6
- name: Verify 3.11.9 - name: Verify 3.6
run: python __tests__/verify-python.py 3.11.9 run: python __tests__/verify-python.py 3.6
- name: Run with setup-python 3.12.7 - name: Run with setup-python 3.7
uses: ./ uses: ./
with: with:
python-version: 3.12.7 python-version: 3.7
- name: Verify 3.12.7 - name: Verify 3.7
run: python __tests__/verify-python.py 3.12.7 run: python __tests__/verify-python.py 3.7
- name: Run with setup-python 3.13.0 - name: Run with setup-python 3.8
uses: ./ uses: ./
with: with:
python-version: 3.13.0 python-version: 3.8
- name: Verify 3.13.0 - name: Verify 3.8
run: python __tests__/verify-python.py 3.13.0 run: python __tests__/verify-python.py 3.8
- name: Run with setup-python 3.13 - name: Run with setup-python 3.7.5
id: cp313
uses: ./ uses: ./
with: with:
python-version: '3.13' python-version: 3.7.5
- name: Verify 3.13 - name: Verify 3.7.5
run: python __tests__/verify-python.py 3.13 run: python __tests__/verify-python.py 3.7.5
- name: Run python-path sample 3.13
run: pipx run --python '${{ steps.cp313.outputs.python-path }}' nox --version
- name: Run with setup-python ==3.13 - name: Run with setup-python 3.6.7
uses: ./ uses: ./
with: with:
python-version: '==3.13' python-version: 3.6.7
- name: Verify ==3.13 - name: Verify 3.6.7
run: python __tests__/verify-python.py 3.13 run: python __tests__/verify-python.py 3.6.7
- name: Run with setup-python <3.13 - name: Run with setup-python 3.8.1
uses: ./ uses: ./
with: with:
python-version: '<3.13' python-version: 3.8.1
- name: Verify <3.13 - name: Verify 3.8.1
run: python __tests__/verify-python.py 3.12 run: python __tests__/verify-python.py 3.8.1
- name: Test Raw Endpoint Access
run: | - name: Run with setup-python 3.10
curl -L https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json | jq empty id: cp310
shell: bash uses: ./
with:
python-version: "3.10"
- name: Verify 3.10
run: python __tests__/verify-python.py 3.10
- name: Run python-path sample 3.10
run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version

View File

@ -1,20 +0,0 @@
name: 'Publish Immutable Action Version'
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
packages: write
steps:
- name: Checking out
uses: actions/checkout@v4
- name: Publish
id: publish
uses: actions/publish-immutable-action@v0.0.4

View File

@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Update the ${{ env.TAG_NAME }} tag - name: Update the ${{ env.TAG_NAME }} tag
uses: actions/publish-action@v0.3.0 uses: actions/publish-action@v0.2.1
with: with:
source-tag: ${{ env.TAG_NAME }} source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }} slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

View File

@ -1,135 +0,0 @@
name: Validate GraalPy e2e
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
jobs:
setup-graalpy:
name: Setup GraalPy ${{ matrix.graalpy }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
graalpy:
- 'graalpy-22.3'
- 'graalpy-23.0'
- 'graalpy-23.1'
- 'graalpy-24.1'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python ${{ matrix.graalpy }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.graalpy }}
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: GraalPy and Python version
run: python --version
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
- name: Assert GraalPy is running
run: |
import platform
assert platform.python_implementation().lower() == "graalvm"
shell: python
- name: Assert expected binaries (or symlinks) are present
run: |
EXECUTABLE=${{ matrix.graalpy }}
EXECUTABLE=${EXECUTABLE/graalpy-/graalpy} # remove the first '-' in "graalpy-X.Y" -> "graalpyX.Y" to match executable name
EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
${EXECUTABLE} --version
shell: bash
setup-graalpy-noenv:
name: Setup GraalPy ${{ matrix.graalpy }} ${{ matrix.os }} (noenv)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
graalpy: ['graalpy22.3', 'graalpy23.0', 'graalpy23.1', 'graalpy24.1']
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python ${{ matrix.graalpy }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.graalpy }}
update-environment: false
- name: GraalPy and Python version
run: ${{ steps.setup-python.outputs.python-path }} --version
- name: Run simple code
run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))'
check-latest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, macos-13]
steps:
- uses: actions/checkout@v4
- name: Setup GraalPy and check latest
uses: ./
id: graalpy
with:
python-version: 'graalpy-24.x'
check-latest: true
- name: GraalPy and Python version
run: python --version
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
- name: Assert GraalPy is running
run: |
import platform
assert platform.python_implementation().lower() == "graalvm"
shell: python
- name: Assert expected binaries (or symlinks) are present
run: |
EXECUTABLE='${{ steps.graalpy.outputs.python-version }}'
EXECUTABLE="${EXECUTABLE%.*}"
${EXECUTABLE} --version
shell: bash

View File

@ -11,7 +11,6 @@ on:
- '**.md' - '**.md'
schedule: schedule:
- cron: 30 3 * * * - cron: 30 3 * * *
workflow_dispatch:
jobs: jobs:
setup-pypy: setup-pypy:
@ -20,86 +19,23 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
pypy: pypy:
- 'pypy-2.7' - 'pypy-2.7'
- 'pypy-3.10' - 'pypy-3.7'
- 'pypy3.9' - 'pypy3.9'
- 'pypy-2.7-v7.3.17' - 'pypy-2.7-v7.3.4'
- 'pypy-3.10-v7.3.17' - 'pypy-3.7-v7.3.5'
- 'pypy-3.10-v7.3.16' - 'pypy-3.7-v7.3.4'
- 'pypy-3.10-v7.3.x' - 'pypy-3.7-v7.3.x'
- 'pypy-3.10-v7.x' - 'pypy-3.7-v7.x'
- 'pypy-2.7-v7.3.12rc1' - 'pypy-2.7-v7.3.4rc1'
- 'pypy-3.10-nightly' - 'pypy-3.7-nightly'
- 'pypy3.10-v7.3.17' - 'pypy3.8-v7.3.7'
- 'pypy3.11-v7.3.19'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: setup-python ${{ matrix.pypy }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.pypy }}
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: PyPy and Python version
run: python --version
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
- name: Assert PyPy is running
run: |
import platform
assert platform.python_implementation().lower() == "pypy"
shell: python
- name: Assert expected binaries (or symlinks) are present
run: |
EXECUTABLE=${{ matrix.pypy }}
EXECUTABLE=${EXECUTABLE/pypy-/pypy} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
${EXECUTABLE} --version
shell: bash
check-non-eol:
name: Check non-eol ${{ matrix.pypy }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- macos-13
- macos-14
- macos-15
- windows-2019
- windows-2022
- windows-2025
- ubuntu-22.04
- ubuntu-24.04
- ubuntu-22.04-arm
- ubuntu-24.04-arm
pypy: ['pypy-2.7', 'pypy-3.10', 'pypy-3.11']
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python ${{ matrix.pypy }} - name: setup-python ${{ matrix.pypy }}
id: setup-python id: setup-python
@ -137,21 +73,12 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
[ pypy: ['pypy2.7', 'pypy3.7', 'pypy3.8', 'pypy3.9-nightly']
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
pypy: ['pypy2.7', 'pypy3.9', 'pypy3.10-nightly', 'pypy3.11']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: setup-python ${{ matrix.pypy }} - name: setup-python ${{ matrix.pypy }}
id: setup-python id: setup-python
@ -171,22 +98,13 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup PyPy and check latest - name: Setup PyPy and check latest
uses: ./ uses: ./
with: with:
python-version: 'pypy-3.11-v7.3.x' python-version: 'pypy-3.7-v7.3.x'
check-latest: true check-latest: true
- name: PyPy and Python version - name: PyPy and Python version
run: python --version run: python --version
@ -202,7 +120,7 @@ jobs:
- name: Assert expected binaries (or symlinks) are present - name: Assert expected binaries (or symlinks) are present
run: | run: |
EXECUTABLE="pypy-3.11-v7.3.x" EXECUTABLE="pypy-3.7-v7.3.x"
EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
${EXECUTABLE} --version ${EXECUTABLE} --version
@ -213,25 +131,15 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup PyPy and check latest - name: Setup PyPy and check latest
uses: ./ uses: ./
with: with:
python-version: | python-version: |
pypy-3.11-v7.3.x pypy-3.7-v7.3.x
pypy-3.10-v7.3.x pypy3.8
pypy3.9
check-latest: true check-latest: true
- name: PyPy and Python version - name: PyPy and Python version
run: python --version run: python --version
@ -247,14 +155,14 @@ jobs:
- name: Assert expected binaries (or symlinks) are present - name: Assert expected binaries (or symlinks) are present
run: | run: |
EXECUTABLE="pypy-3.11-v7.3.x" EXECUTABLE="pypy-3.7-v7.3.x"
EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
${EXECUTABLE} --version ${EXECUTABLE} --version
shell: bash shell: bash
- name: Assert expected binaries (or symlinks) are present - name: Assert expected binaries (or symlinks) are present
run: | run: |
EXECUTABLE='pypy3.9' EXECUTABLE='pypy3.8'
EXECUTABLE=${EXECUTABLE/pypy-/pypy} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name EXECUTABLE=${EXECUTABLE/pypy-/pypy} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
${EXECUTABLE} --version ${EXECUTABLE} --version

View File

@ -1,486 +0,0 @@
name: Validate Python e2e freethread
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
schedule:
- cron: 30 3 * * *
workflow_dispatch:
jobs:
setup-versions-from-manifest:
name: Setup ${{ matrix.python }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} version file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: .python-version
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-file-without-parameter:
name: Setup ${{ matrix.python }} ${{ matrix.os }} version file without parameter
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-standard-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} standard pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.0, 3.13.1, 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: |
echo '[project]
requires-python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
freethreaded: true
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-poetry-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} poetry pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.0, 3.13.1, 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: |
echo '[tool.poetry.dependencies]
python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
freethreaded: true
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-tool-versions-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} .tool-versions file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.0t, 3.13.1t, 3.13.2t, 3.14t-dev]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-tool-versions-file ${{ matrix.python }}
run: |
echo "python ${{ matrix.python }}" > .tool-versions
- name: setup-python using .tool-versions ${{ matrix.python }}
id: setup-python-tool-versions
uses: ./
with:
python-version-file: .tool-versions
setup-pre-release-version-from-manifest:
name: Setup 3.14.0-alpha.6 ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python 3.14.0-alpha.6
id: setup-python
uses: ./
with:
python-version: '3.14.0-alpha.6'
freethreaded: true
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-dev-version:
name: Setup 3.14t-dev ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python 3.14t-dev
id: setup-python
uses: ./
with:
python-version: '3.14t-dev'
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-prerelease-version:
name: Setup 3.14t ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python 3.14t
id: setup-python
uses: ./
with:
python-version: '3.14t'
allow-prereleases: true
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-noenv:
name: Setup ${{ matrix.python }} ${{ matrix.os }} (noenv)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
update-environment: false
- name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV
- name: Run simple code
run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))'
check-latest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
python-version: [3.13t, 3.14t-dev]
steps:
- uses: actions/checkout@v4
- name: Setup Python and check latest
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV
setup-python-multiple-python-versions:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps:
- uses: actions/checkout@v4
- name: Setup Python and check latest
id: setup-python
uses: ./
with:
python-version: |
3.13.1t
3.13.2t
3.14t-dev
- name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV
setup-versions-with-freethread-input:
name: Setup ${{ matrix.python }} ${{ matrix.os }} using freethread input parameter
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-20.04,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.13.1, 3.13.2, 3.14-dev, 3.14.0-alpha.6]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
freethreaded: true
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate GIL
run: python ./__tests__/verify-freethreaded.py

View File

@ -20,20 +20,11 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
[ python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: setup-python ${{ matrix.python }} - name: setup-python ${{ matrix.python }}
id: setup-python id: setup-python
@ -64,20 +55,11 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
[ python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version run: echo ${{ matrix.python }} > .python-version
@ -86,7 +68,7 @@ jobs:
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version-file: .python-version python-version-file: '.python-version'
- name: Check python-path - name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
@ -105,210 +87,22 @@ jobs:
- name: Run simple code - name: Run simple code
run: python -c 'import math; print(math.factorial(5))' run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-file-without-parameter:
name: Setup ${{ matrix.python }} ${{ matrix.os }} version file without parameter
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-standard-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} standard pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, '==3.12.3', 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: |
echo '[project]
requires-python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}".replace("==", "") -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-poetry-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} poetry pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: |
echo '[tool.poetry.dependencies]
python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-tool-versions-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} .tool-versions file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [pypy3.11-7.3.18, graalpy-24.1.2, 3.13.2, 3.14-dev]
exclude:
- os: windows-latest
python: graalpy-24.1.2
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-tool-versions-file ${{ matrix.python }}
run: |
echo "python ${{ matrix.python }}" > .tool-versions
- name: setup-python using .tool-versions ${{ matrix.python }}
id: setup-python-tool-versions
uses: ./
with:
python-version-file: .tool-versions
setup-pre-release-version-from-manifest: setup-pre-release-version-from-manifest:
name: Setup 3.14.0-alpha.6 ${{ matrix.os }} name: Setup 3.9.0-beta.4 ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: setup-python 3.14.0-alpha.6 - name: setup-python 3.9.0-beta.4
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.14.0-alpha.6' python-version: '3.9.0-beta.4'
- name: Check python-path - name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
@ -317,8 +111,8 @@ jobs:
- name: Validate version - name: Validate version
run: | run: |
$pythonVersion = (python --version) $pythonVersion = (python --version)
if ("Python 3.14.0a6" -ne "$pythonVersion"){ if ("Python 3.9.0b4" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is 3.14.0a6" Write-Host "The current version is $pythonVersion; expected version is 3.9.0b4"
exit 1 exit 1
} }
$pythonVersion $pythonVersion
@ -328,75 +122,28 @@ jobs:
run: python -c 'import math; print(math.factorial(5))' run: python -c 'import math; print(math.factorial(5))'
setup-dev-version: setup-dev-version:
name: Setup 3.14-dev ${{ matrix.os }} name: Setup 3.9-dev ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [macos-latest, windows-latest, ubuntu-latest]
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: setup-python 3.14-dev - name: setup-python 3.9-dev
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.14-dev' python-version: '3.9-dev'
- name: Check python-path - name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash shell: bash
- name: Validate version - name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }} run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.9.') }}
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-prerelease-version:
name: Setup 3.14 ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python 3.14
id: setup-python
uses: ./
with:
python-version: '3.14'
allow-prereleases: true
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash shell: bash
- name: Run simple code - name: Run simple code
@ -408,20 +155,11 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
[ python: ["3.7", "3.8", "3.9", "3.10"]
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: setup-python ${{ matrix.python }} - name: setup-python ${{ matrix.python }}
id: setup-python id: setup-python
@ -441,19 +179,10 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[ python-version: ["3.8", "3.9", "3.10"]
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup Python and check latest - name: Setup Python and check latest
uses: ./ uses: ./
with: with:
@ -474,33 +203,23 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os: [ubuntu-latest, windows-latest, macos-latest]
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Setup Python and check latest - name: Setup Python and check latest
uses: ./ uses: ./
with: with:
python-version: | python-version: |
3.7
3.8
3.9 3.9
3.10 3.10
3.11
3.12
3.13
check-latest: true check-latest: true
- name: Validate version - name: Validate version
run: | run: |
$pythonVersion = (python --version) $pythonVersion = (python --version)
if ("$pythonVersion" -NotMatch "3.13"){ if ("$pythonVersion" -NotMatch "3.10"){
Write-Host "The current version is $pythonVersion; expected version is 3.13" Write-Host "The current version is $pythonVersion; expected version is 3.10"
exit 1 exit 1
} }
$pythonVersion $pythonVersion

View File

@ -1,11 +0,0 @@
name: Update configuration files
on:
schedule:
- cron: '0 3 * * 0'
workflow_dispatch:
jobs:
call-update-configuration-files:
name: Update configuration files
uses: actions/reusable-workflows/.github/workflows/update-config-files.yml@main

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/form-data-3.0.1.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/psl.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/punycode.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/tough-cookie-3.0.1.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/tough-cookie-4.0.0.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/universalify.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +0,0 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!.github/
!src/

View File

@ -1,11 +0,0 @@
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: false,
arrowParens: 'avoid'
};

11
.prettierrc.json Normal file
View File

@ -0,0 +1,11 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid",
"parser": "typescript"
}

View File

@ -1,9 +1,8 @@
# setup-python # setup-python
[![Basic validation](https://github.com/actions/setup-python/actions/workflows/basic-validation.yml/badge.svg?branch=main)](https://github.com/actions/setup-python/actions/workflows/basic-validation.yml) <p align="left">
[![Validate Python e2e](https://github.com/actions/setup-python/actions/workflows/test-python.yml/badge.svg?branch=main)](https://github.com/actions/setup-python/actions/workflows/test-python.yml) <a href="https://github.com/actions/setup-python"><img alt="GitHub Actions status" src="https://github.com/actions/setup-python/workflows/Main%20workflow/badge.svg"></a>
[![Validate PyPy e2e](https://github.com/actions/setup-python/actions/workflows/test-pypy.yml/badge.svg?branch=main)](https://github.com/actions/setup-python/actions/workflows/test-pypy.yml) </p>
[![e2e-cache](https://github.com/actions/setup-python/actions/workflows/e2e-cache.yml/badge.svg?branch=main)](https://github.com/actions/setup-python/actions/workflows/e2e-cache.yml)
This action provides the following functionality for GitHub Actions users: This action provides the following functionality for GitHub Actions users:
@ -18,43 +17,22 @@ See [action.yml](action.yml)
**Python** **Python**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.10'
- run: python my_script.py - run: python my_script.py
``` ```
**PyPy** **PyPy**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: 'pypy3.10' python-version: 'pypy3.9'
- run: python my_script.py - run: python my_script.py
``` ```
**GraalPy**
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 'graalpy-24.0'
- run: python my_script.py
```
**Free threaded Python**
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13t'
- run: python my_script.py
```
The `python-version` input is optional. If not supplied, the action will try to resolve the version from the default `.python-version` file. If the `.python-version` file doesn't exist Python or PyPy version from the PATH will be used. The default version of Python or PyPy in PATH varies between runners and can be changed unexpectedly so we recommend always setting Python version explicitly using the `python-version` or `python-version-file` inputs. The `python-version` input is optional. If not supplied, the action will try to resolve the version from the default `.python-version` file. If the `.python-version` file doesn't exist Python or PyPy version from the PATH will be used. The default version of Python or PyPy in PATH varies between runners and can be changed unexpectedly so we recommend always setting Python version explicitly using the `python-version` or `python-version-file` inputs.
The action will first check the local [tool cache](docs/advanced-usage.md#hosted-tool-cache) for a [semver](https://github.com/npm/node-semver#versions) match. If unable to find a specific version in the tool cache, the action will attempt to download a version of Python from [GitHub Releases](https://github.com/actions/python-versions/releases) and for PyPy from the official [PyPy's dist](https://downloads.python.org/pypy/). The action will first check the local [tool cache](docs/advanced-usage.md#hosted-tool-cache) for a [semver](https://github.com/npm/node-semver#versions) match. If unable to find a specific version in the tool cache, the action will attempt to download a version of Python from [GitHub Releases](https://github.com/actions/python-versions/releases) and for PyPy from the official [PyPy's dist](https://downloads.python.org/pypy/).
@ -67,13 +45,13 @@ The `python-version` input supports the [Semantic Versioning Specification](http
## Supported architectures ## Supported architectures
Using the `architecture` input, it is possible to specify the required Python or PyPy interpreter architecture: `x86`, `x64`, or `arm64`. If the input is not specified, the architecture defaults to the host OS architecture. Using `architecture` input it is possible to specify the required Python or PyPy interpreter architecture: `x86` or `x64`. If the input is not specified the architecture defaults to `x64`.
## Caching packages dependencies ## Caching packages dependencies
The action has built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default. The action has built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default.
The action defaults to searching for a dependency file (`requirements.txt` or `pyproject.toml` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Input `cache-dependency-path` is used for cases when multiple dependency files are used, they are located in different subdirectories or different files for the hash that want to be used. The action defaults to searching for a dependency file (`requirements.txt` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Input `cache-dependency-path` is used for cases when multiple dependency files are used, they are located in different subdirectories or different files for the hash that want to be used.
- For `pip`, the action will cache the global cache directory - For `pip`, the action will cache the global cache directory
- For `pipenv`, the action will cache virtualenv directory - For `pipenv`, the action will cache virtualenv directory
@ -83,10 +61,10 @@ The action defaults to searching for a dependency file (`requirements.txt` or `p
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.9'
cache: 'pip' # caching pip dependencies cache: 'pip' # caching pip dependencies
- run: pip install -r requirements.txt - run: pip install -r requirements.txt
``` ```
@ -103,20 +81,10 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet
- [Check latest version](docs/advanced-usage.md#check-latest-version) - [Check latest version](docs/advanced-usage.md#check-latest-version)
- [Caching packages](docs/advanced-usage.md#caching-packages) - [Caching packages](docs/advanced-usage.md#caching-packages)
- [Outputs and environment variables](docs/advanced-usage.md#outputs-and-environment-variables) - [Outputs and environment variables](docs/advanced-usage.md#outputs-and-environment-variables)
- [Available versions of Python, PyPy and GraalPy](docs/advanced-usage.md#available-versions-of-python-pypy-and-graalpy) - [Available versions of Python and PyPy](docs/advanced-usage.md#available-versions-of-python-and-pypy)
- [Hosted tool cache](docs/advanced-usage.md#hosted-tool-cache) - [Hosted tool cache](docs/advanced-usage.md#hosted-tool-cache)
- [Using `setup-python` with a self-hosted runner](docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner) - [Using `setup-python` with a self-hosted runner](docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner)
- [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes) - [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes)
- [Allow pre-releases](docs/advanced-usage.md#allow-pre-releases)
## Recommended permissions
When using the `setup-python` action in your GitHub Actions workflow, it is recommended to set the following permissions to ensure proper functionality:
```yaml
permissions:
contents: read # access to check out code and install dependencies
```
## License ## License

View File

@ -5,10 +5,11 @@ import * as exec from '@actions/exec';
import * as io from '@actions/io'; import * as io from '@actions/io';
import {getCacheDistributor} from '../src/cache-distributions/cache-factory'; import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
import {State} from '../src/cache-distributions/cache-distributor'; import {State} from '../src/cache-distributions/cache-distributor';
import * as utils from './../src/utils';
describe('restore-cache', () => { describe('restore-cache', () => {
const pipFileLockHash = const pipFileLockHash =
'f8428d7cf00ea53a5c3702f0a9cb3cc467f76cd86a34723009350c4e4b32751a'; 'a3bdcc71289e4979ca9e051810d81999cc99823109faf6912e17ff14c8e621a6';
const requirementsHash = const requirementsHash =
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121'; 'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
const requirementsLinuxHash = const requirementsLinuxHash =
@ -94,7 +95,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
async packageManager => { async packageManager => {
expect(() => expect(() =>
getCacheDistributor(packageManager, '3.8.12', undefined) getCacheDistributor(packageManager, '3.8.12', undefined)
).toThrow(`Caching for '${packageManager}' is not supported`); ).toThrowError(`Caching for '${packageManager}' is not supported`);
} }
); );
}); });
@ -163,12 +164,6 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
fileHash, fileHash,
cachePaths cachePaths
) => { ) => {
restoreCacheSpy.mockImplementation(
(cachePaths: string[], primaryKey: string, restoreKey?: string) => {
return primaryKey.includes(fileHash) ? primaryKey : '';
}
);
const cacheDistributor = getCacheDistributor( const cacheDistributor = getCacheDistributor(
packageManager, packageManager,
pythonVersion, pythonVersion,
@ -184,36 +179,28 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
); );
} }
const restoredKeys = restoreCacheSpy.mock.results.map(
result => result.value
);
restoredKeys.forEach(restoredKey => {
if (restoredKey) {
if (process.platform === 'linux' && packageManager === 'pip') { if (process.platform === 'linux' && packageManager === 'pip') {
expect(infoSpy).toHaveBeenCalledWith( expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}-20.04-Ubuntu-python-${pythonVersion}-${packageManager}-${fileHash}` `Cache restored from key: setup-python-${process.env['RUNNER_OS']}-20.04-Ubuntu-python-${pythonVersion}-${packageManager}-${fileHash}`
); );
} else if (packageManager === 'poetry') { } else if (packageManager === 'poetry') {
expect(infoSpy).toHaveBeenCalledWith( expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}-python-${pythonVersion}-${packageManager}-v2-${fileHash}` `Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-v2-${fileHash}`
); );
} else { } else {
expect(infoSpy).toHaveBeenCalledWith( expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}-python-${pythonVersion}-${packageManager}-${fileHash}` `Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-${fileHash}`
); );
} }
} else {
expect(infoSpy).toHaveBeenCalledWith(
`${packageManager} cache is not found`
);
}
});
}, },
30000 30000
); );
it.each([['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']])( it.each([
['pip', '3.8.12', 'requirements-linux.txt', 'requirements-linux.txt'],
['pip', '3.8.12', 'requirements.txt', 'requirements.txt'],
['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']
])(
'Should throw an error because dependency file is not found', 'Should throw an error because dependency file is not found',
async ( async (
packageManager, packageManager,
@ -226,47 +213,13 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
pythonVersion, pythonVersion,
dependencyFile dependencyFile
); );
await expect(cacheDistributor.restoreCache()).rejects.toThrowError(
await expect(cacheDistributor.restoreCache()).rejects.toThrow(
`No file in ${process.cwd()} matched to [${cacheDependencyPath `No file in ${process.cwd()} matched to [${cacheDependencyPath
.split('\n') .split('\n')
.join(',')}], make sure you have checked out the target repository` .join(',')}], make sure you have checked out the target repository`
); );
} }
); );
it.each([
['pip', '3.8.12', 'requirements-linux.txt'],
['pip', '3.8.12', 'requirements.txt']
])(
'Shouldn`t throw an error as there is a default file `pyproject.toml` to use when requirements.txt is not specified',
async (packageManager, pythonVersion, dependencyFile) => {
const cacheDistributor = getCacheDistributor(
packageManager,
pythonVersion,
dependencyFile
);
await expect(cacheDistributor.restoreCache()).resolves.not.toThrow();
}
);
it.each([
['pip', '3.8.12', 'requirements-linux.txt'],
['pip', '3.8.12', 'requirements.txt']
])(
'Should throw an error as there is no default file `pyproject.toml` to use when requirements.txt is not specified',
async (packageManager, pythonVersion, dependencyFile) => {
const cacheDistributor = getCacheDistributor(
packageManager,
pythonVersion,
dependencyFile
) as any; // Widening PipCache | PipenvCache | PoetryCache type to any allow us to change private property on the cacheDistributor to test value: "**/pyprojecttest.toml"
cacheDistributor.cacheDependencyBackupPath = '**/pyprojecttest.toml';
await expect(cacheDistributor.restoreCache()).rejects.toThrow();
}
);
}); });
describe('Dependencies changed', () => { describe('Dependencies changed', () => {

View File

@ -87,7 +87,6 @@ describe('run', () => {
describe('Validate unchanged cache is not saved', () => { describe('Validate unchanged cache is not saved', () => {
it('should not save cache for pip', async () => { it('should not save cache for pip', async () => {
inputs['cache'] = 'pip'; inputs['cache'] = 'pip';
inputs['python-version'] = '3.10.0';
await run(); await run();
@ -104,7 +103,22 @@ describe('run', () => {
it('should not save cache for pipenv', async () => { it('should not save cache for pipenv', async () => {
inputs['cache'] = 'pipenv'; inputs['cache'] = 'pipenv';
inputs['python-version'] = '3.10.0';
await run();
expect(getInputSpy).toHaveBeenCalled();
expect(debugSpy).toHaveBeenCalledWith(
`paths for caching are ${__dirname}`
);
expect(getStateSpy).toHaveBeenCalledTimes(3);
expect(infoSpy).toHaveBeenCalledWith(
`Cache hit occurred on the primary key ${requirementsHash}, not saving cache.`
);
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('should not save cache for pipenv', async () => {
inputs['cache'] = 'pipenv';
await run(); await run();
@ -123,7 +137,6 @@ describe('run', () => {
describe('action saves the cache', () => { describe('action saves the cache', () => {
it('saves cache from pip', async () => { it('saves cache from pip', async () => {
inputs['cache'] = 'pip'; inputs['cache'] = 'pip';
inputs['python-version'] = '3.10.0';
getStateSpy.mockImplementation((name: string) => { getStateSpy.mockImplementation((name: string) => {
if (name === State.CACHE_MATCHED_KEY) { if (name === State.CACHE_MATCHED_KEY) {
return requirementsHash; return requirementsHash;
@ -150,7 +163,6 @@ describe('run', () => {
it('saves cache from pipenv', async () => { it('saves cache from pipenv', async () => {
inputs['cache'] = 'pipenv'; inputs['cache'] = 'pipenv';
inputs['python-version'] = '3.10.0';
getStateSpy.mockImplementation((name: string) => { getStateSpy.mockImplementation((name: string) => {
if (name === State.CACHE_MATCHED_KEY) { if (name === State.CACHE_MATCHED_KEY) {
return pipFileLockHash; return pipFileLockHash;
@ -177,7 +189,6 @@ describe('run', () => {
it('saves cache from poetry', async () => { it('saves cache from poetry', async () => {
inputs['cache'] = 'poetry'; inputs['cache'] = 'poetry';
inputs['python-version'] = '3.10.0';
getStateSpy.mockImplementation((name: string) => { getStateSpy.mockImplementation((name: string) => {
if (name === State.CACHE_MATCHED_KEY) { if (name === State.CACHE_MATCHED_KEY) {
return poetryLockHash; return poetryLockHash;
@ -204,7 +215,6 @@ describe('run', () => {
it('saves with -1 cacheId , should not fail workflow', async () => { it('saves with -1 cacheId , should not fail workflow', async () => {
inputs['cache'] = 'poetry'; inputs['cache'] = 'poetry';
inputs['python-version'] = '3.10.0';
getStateSpy.mockImplementation((name: string) => { getStateSpy.mockImplementation((name: string) => {
if (name === State.STATE_CACHE_PRIMARY_KEY) { if (name === State.STATE_CACHE_PRIMARY_KEY) {
return poetryLockHash; return poetryLockHash;
@ -231,9 +241,8 @@ describe('run', () => {
expect(setFailedSpy).not.toHaveBeenCalled(); expect(setFailedSpy).not.toHaveBeenCalled();
}); });
it('saves with error from toolkit, should not fail the workflow', async () => { it('saves with error from toolkit, should fail workflow', async () => {
inputs['cache'] = 'npm'; inputs['cache'] = 'npm';
inputs['python-version'] = '3.10.0';
getStateSpy.mockImplementation((name: string) => { getStateSpy.mockImplementation((name: string) => {
if (name === State.STATE_CACHE_PRIMARY_KEY) { if (name === State.STATE_CACHE_PRIMARY_KEY) {
return poetryLockHash; return poetryLockHash;
@ -254,7 +263,7 @@ describe('run', () => {
expect(getStateSpy).toHaveBeenCalledTimes(3); expect(getStateSpy).toHaveBeenCalledTimes(3);
expect(infoSpy).not.toHaveBeenCalledWith(); expect(infoSpy).not.toHaveBeenCalledWith();
expect(saveCacheSpy).toHaveBeenCalled(); expect(saveCacheSpy).toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled(); expect(setFailedSpy).toHaveBeenCalled();
}); });
}); });

View File

@ -4,8 +4,8 @@ verify_ssl = true
name = "pypi" name = "pypi"
[packages] [packages]
flake8 = "==6.0.0" flake8 = "==4.0.1"
numpy = "==2.2.4" numpy = "==1.23.0"
[dev-packages] [dev-packages]

View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "9d0bc7ff1f9078396b19f05bc5cd57894f3783c68f96fa9d623b1ea5a1b168f5" "sha256": "e9c37110984955621040e2dc8548c026eb8466c23db1b8e69430289b10be8938"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -18,98 +18,62 @@
"default": { "default": {
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7", "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d",
"sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181" "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "version": "==4.0.1"
"version": "==6.0.0"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
], ],
"markers": "python_version >= '3.6'", "version": "==0.6.1"
"version": "==0.7.0"
}, },
"numpy": { "numpy": {
"hashes": [ "hashes": [
"sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286", "sha256:092f5e6025813e64ad6d1b52b519165d08c730d099c114a9247c9bb635a2a450",
"sha256:0d54974f9cf14acf49c60f0f7f4084b6579d24d439453d5fc5805d46a165b542", "sha256:196cd074c3f97c4121601790955f915187736f9cf458d3ee1f1b46aff2b1ade0",
"sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f", "sha256:1c29b44905af288b3919803aceb6ec7fec77406d8b08aaa2e8b9e63d0fe2f160",
"sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d", "sha256:2b2da66582f3a69c8ce25ed7921dcd8010d05e59ac8d89d126a299be60421171",
"sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0", "sha256:5043bcd71fcc458dfb8a0fc5509bbc979da0131b9d08e3d5f50fb0bbb36f169a",
"sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7", "sha256:58bfd40eb478f54ff7a5710dd61c8097e169bc36cc68333d00a9bcd8def53b38",
"sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3", "sha256:79a506cacf2be3a74ead5467aee97b81fca00c9c4c8b3ba16dbab488cd99ba10",
"sha256:218f061d2faa73621fa23d6359442b0fc658d5b9a70801373625d958259eaca3", "sha256:94b170b4fa0168cd6be4becf37cb5b127bd12a795123984385b8cd4aca9857e5",
"sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146", "sha256:97a76604d9b0e79f59baeca16593c711fddb44936e40310f78bfef79ee9a835f",
"sha256:2fa8fa7697ad1646b5c93de1719965844e004fcad23c91228aca1cf0800044a1", "sha256:98e8e0d8d69ff4d3fa63e6c61e8cfe2d03c29b16b58dbef1f9baa175bbed7860",
"sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6", "sha256:ac86f407873b952679f5f9e6c0612687e51547af0e14ddea1eedfcb22466babd",
"sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc", "sha256:ae8adff4172692ce56233db04b7ce5792186f179c415c37d539c25de7298d25d",
"sha256:4ba5054787e89c59c593a4169830ab362ac2bee8a969249dc56e5d7d20ff8df9", "sha256:bd3fa4fe2e38533d5336e1272fc4e765cabbbde144309ccee8675509d5cd7b05",
"sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592", "sha256:d0d2094e8f4d760500394d77b383a1b06d3663e8892cdf5df3c592f55f3bff66",
"sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00", "sha256:d54b3b828d618a19779a84c3ad952e96e2c2311b16384e973e671aa5be1f6187",
"sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298", "sha256:d6ca8dabe696c2785d0c8c9b0d8a9b6e5fdbe4f922bde70d57fa1a2848134f95",
"sha256:7051ee569db5fbac144335e0f3b9c2337e0c8d5c9fee015f259a5bd70772b7e8", "sha256:d8cc87bed09de55477dba9da370c1679bd534df9baa171dd01accbb09687dac3",
"sha256:7716e4a9b7af82c06a2543c53ca476fa0b57e4d760481273e09da04b74ee6ee2", "sha256:f0f18804df7370571fb65db9b98bf1378172bd4e962482b857e612d1fec0f53e",
"sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392", "sha256:f1d88ef79e0a7fa631bb2c3dda1ea46b32b1fe614e10fedd611d3d5398447f2f",
"sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb", "sha256:f9c3fc2adf67762c9fe1849c859942d23f8d3e0bee7b5ed3d4a9c3eeb50a2f07",
"sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8", "sha256:fc431493df245f3c627c0c05c2bd134535e7929dbe2e602b80e42bf52ff760bc",
"sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd", "sha256:fe8b9683eb26d2c4d5db32cd29b38fdcf8381324ab48313b5b69088e0e355379"
"sha256:8146f3550d627252269ac42ae660281d673eb6f8b32f113538e0cc2a9aed42b9",
"sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0",
"sha256:892c10d6a73e0f14935c31229e03325a7b3093fafd6ce0af704be7f894d95687",
"sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc",
"sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f",
"sha256:9eeea959168ea555e556b8188da5fa7831e21d91ce031e95ce23747b7609f8a4",
"sha256:a0258ad1f44f138b791327961caedffbf9612bfa504ab9597157806faa95194a",
"sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39",
"sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4",
"sha256:a84eda42bd12edc36eb5b53bbcc9b406820d3353f1994b6cfe453a33ff101775",
"sha256:ab2939cd5bec30a7430cbdb2287b63151b77cf9624de0532d629c9a1c59b1d5c",
"sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd",
"sha256:adf8c1d66f432ce577d0197dceaac2ac00c0759f573f28516246351c58a85020",
"sha256:b4adfbbc64014976d2f91084915ca4e626fbf2057fb81af209c1a6d776d23e3d",
"sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24",
"sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7",
"sha256:bd3ad3b0a40e713fc68f99ecfd07124195333f1e689387c180813f0e94309d6f",
"sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba",
"sha256:cf28633d64294969c019c6df4ff37f5698e8326db68cc2b66576a51fad634880",
"sha256:d0f35b19894a9e08639fd60a1ec1978cb7f5f7f1eace62f38dd36be8aecdef4d",
"sha256:db1f1c22173ac1c58db249ae48aa7ead29f534b9a948bc56828337aa84a32ed6",
"sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854",
"sha256:df2f57871a96bbc1b69733cd4c51dc33bea66146b8c63cacbfed73eec0883017",
"sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8",
"sha256:e642d86b8f956098b564a45e6f6ce68a22c2c97a04f5acd3f221f57b8cb850ae",
"sha256:e9e0a277bb2eb5d8a7407e14688b85fd8ad628ee4e0c7930415687b6564207a4",
"sha256:ea2bb7e2ae9e37d96835b3576a4fa4b3a97592fbea8ef7c3587078b0068b8f09",
"sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff",
"sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960",
"sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee",
"sha256:f4162988a360a29af158aeb4a2f4f09ffed6a969c9776f8f3bdee9b06a8ab7e5",
"sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c",
"sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.10'", "version": "==1.23.0"
"version": "==2.2.4"
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053", "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20",
"sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610" "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.10.0" "version": "==2.8.0"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
"sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf", "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c",
"sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd" "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==3.0.1" "version": "==2.4.0"
} }
}, },
"develop": {} "develop": {}

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
numpy==2.2.4 numpy==1.22.3
flake8==6.0.0 pandas==1.4.2

View File

@ -1,226 +1,413 @@
# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
[[package]] [[package]]
name = "altgraph" name = "altgraph"
version = "0.17.4" version = "0.17.2"
description = "Python graph (network) package" description = "Python graph (network) package"
category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [
{file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"},
{file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"},
]
[[package]] [[package]]
name = "flake8" name = "certifi"
version = "4.0.1" version = "2020.6.20"
description = "the modular source code checker: pep8 pyflakes and co" description = "Python package for providing Mozilla's CA Bundle."
category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = "*"
files = [
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
]
[package.dependencies]
mccabe = ">=0.6.0,<0.7.0"
pycodestyle = ">=2.8.0,<2.9.0"
pyflakes = ">=2.4.0,<2.5.0"
[[package]] [[package]]
name = "importlib-metadata" name = "chardet"
version = "8.5.0" version = "3.0.4"
description = "Read metadata from Python packages" description = "Universal encoding detector for Python 2 and 3"
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = "*"
files = [
{file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, [[package]]
{file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, name = "dis3"
] version = "0.1.3"
description = "Python 2.7 backport of the \"dis\" module from Python 3.5+"
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "docutils"
version = "0.16"
description = "Docutils -- Python Documentation Utilities"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "future"
version = "0.18.2"
description = "Clean single-source support for Python 3 and 2"
category = "main"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "idna"
version = "2.9"
description = "Internationalized Domain Names in Applications (IDNA)"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "itsdangerous"
version = "1.1.0"
description = "Various helpers to pass data to untrusted environments and back."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "kivy"
version = "1.11.1"
description = "A software library for rapid development of hardware-accelerated multitouch applications."
category = "main"
optional = false
python-versions = "*"
[package.dependencies] [package.dependencies]
zipp = ">=3.20" docutils = "*"
Kivy-Garden = ">=0.1.4"
pygments = "*"
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] tuio = ["oscpy"]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"]
perf = ["ipython"]
test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
type = ["pytest-mypy"]
[[package]] [[package]]
name = "macholib" name = "kivy-deps.angle"
version = "1.16.3" version = "0.3.0"
description = "Mach-O header analysis and editing" description = "Repackaged binary dependency of Kivy."
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "kivy-deps.glew"
version = "0.1.12"
description = "Repackaged binary dependency of Kivy."
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "kivy-deps.gstreamer"
version = "0.1.17"
description = "Repackaged binary dependency of Kivy."
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "kivy-deps.sdl2"
version = "0.1.22"
description = "Repackaged binary dependency of Kivy."
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "kivy-garden"
version = "0.1.4"
description = "Garden tool for kivy flowers."
category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [
{file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"},
{file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"},
]
[package.dependencies] [package.dependencies]
altgraph = ">=0.17" requests = "*"
[[package]]
name = "mccabe"
version = "0.6.1"
description = "McCabe checker, plugin for flake8"
optional = false
python-versions = "*"
files = [
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "24.2" version = "21.0"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.6"
files = [
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, [package.dependencies]
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, pyparsing = ">=2.0.2"
]
[[package]]
name = "pdf2image"
version = "1.12.1"
description = "A wrapper around the pdftoppm and pdftocairo command line tools to convert PDF to a PIL Image list."
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
pillow = "*"
[[package]] [[package]]
name = "pefile" name = "pefile"
version = "2024.8.26" version = "2021.9.3"
description = "Python PE parsing module" description = "Python PE parsing module"
category = "main"
optional = false optional = false
python-versions = ">=3.6.0" python-versions = ">=3.6.0"
files = [
{file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"}, [package.dependencies]
{file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"}, future = "*"
]
[[package]] [[package]]
name = "pycodestyle" name = "pillow"
version = "2.8.0" version = "7.2.0"
description = "Python style guide checker" description = "Python Imaging Library (Fork)"
category = "main"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=3.5"
files = [
{file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
{file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
]
[[package]] [[package]]
name = "pyflakes" name = "pygments"
version = "2.4.0" version = "2.6.1"
description = "passive checker of Python programs" description = "Pygments is a syntax highlighting package written in Python."
category = "main"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=3.5"
files = [
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
]
[[package]] [[package]]
name = "pyinstaller" name = "pyinstaller"
version = "6.10.0" version = "3.6"
description = "PyInstaller bundles a Python application and all its dependencies into a single package." description = "PyInstaller bundles a Python application and all its dependencies into a single package."
category = "main"
optional = false optional = false
python-versions = "<3.14,>=3.8" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
{file = "pyinstaller-6.10.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d60fb22859e11483af735aec115fdde09467cdbb29edd9844839f2c920b748c0"},
{file = "pyinstaller-6.10.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:46d75359668993ddd98630a3669dc5249f3c446e35239b43bc7f4155bc574748"},
{file = "pyinstaller-6.10.0-py3-none-manylinux2014_i686.whl", hash = "sha256:3398a98fa17d47ccb31f8779ecbdacec025f7adb2f22757a54b706ac8b4fe906"},
{file = "pyinstaller-6.10.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e9989f354ae4ed8a3bec7bdb37ae0d170751d6520e500f049c7cd0632d31d5c3"},
{file = "pyinstaller-6.10.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b7c90c91921b3749083115b28f30f40abf2bb481ceff196d2b2ce0eaa2b3d429"},
{file = "pyinstaller-6.10.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf876d7d93b8b4f28d1ad57fa24645cf43119c79e985dd5e5f7a801245e6f53"},
{file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:db05e3f2f10f9f78c56f1fb163d9cb453433429fe4281218ebaf1ebfd39ba942"},
{file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:28eca3817f176fdc19747e1afcf434f13bb9f17a644f611be2c5a61b1f498ed7"},
{file = "pyinstaller-6.10.0-py3-none-win32.whl", hash = "sha256:703e041718987e46ba0568a2c71ecf2459fddef57cf9edf3efeed4a53e3dae3f"},
{file = "pyinstaller-6.10.0-py3-none-win_amd64.whl", hash = "sha256:95b55966e563e8b8f31a43882aea10169e9a11fdf38e626d86a2907b640c0701"},
{file = "pyinstaller-6.10.0-py3-none-win_arm64.whl", hash = "sha256:308e0a8670c9c9ac0cebbf1bbb492e71b6675606f2ec78bc4adfc830d209e087"},
{file = "pyinstaller-6.10.0.tar.gz", hash = "sha256:143840f8056ff7b910bf8f16f6cd92cc10a6c2680bb76d0a25d558d543d21270"},
]
[package.dependencies] [package.dependencies]
altgraph = "*" altgraph = "*"
importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} dis3 = "*"
macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""}
packaging = ">=22.0"
pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""}
pyinstaller-hooks-contrib = ">=2024.8"
pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""}
setuptools = ">=42.0.0"
[package.extras]
completion = ["argcomplete"]
hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"]
[[package]] [[package]]
name = "pyinstaller-hooks-contrib" name = "pyparsing"
version = "2025.1" version = "2.4.7"
description = "Community maintained hooks for PyInstaller" description = "Python parsing module"
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "pyinstaller_hooks_contrib-2025.1-py3-none-any.whl", hash = "sha256:d3c799470cbc0bda60dcc8e6b4ab976777532b77621337f2037f558905e3a8e9"},
{file = "pyinstaller_hooks_contrib-2025.1.tar.gz", hash = "sha256:130818f9e9a0a7f2261f1fd66054966a3a50c99d000981c5d1db11d3ad0c6ab2"},
]
[package.dependencies]
importlib_metadata = {version = ">=4.6", markers = "python_version < \"3.10\""}
packaging = ">=22.0"
setuptools = ">=42.0.0"
[[package]] [[package]]
name = "pywin32-ctypes" name = "pywin32-ctypes"
version = "0.2.3" version = "0.2.0"
description = "A (partial) reimplementation of pywin32 using ctypes/cffi" description = ""
category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = "*"
files = [
{file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"},
{file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"},
]
[[package]] [[package]]
name = "setuptools" name = "requests"
version = "75.3.2" version = "2.24.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Python HTTP for Humans."
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
{file = "setuptools-75.3.2-py3-none-any.whl", hash = "sha256:90ab613b6583fc02d5369cbca13ea26ea0e182d1df2d943ee9cbe81d4c61add9"}, [package.dependencies]
{file = "setuptools-75.3.2.tar.gz", hash = "sha256:3c1383e1038b68556a382c1e8ded8887cd20141b0eb5708a6c8d277de49364f5"}, certifi = ">=2017.4.17"
] chardet = ">=3.0.2,<4"
idna = ">=2.5,<3"
urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "ruff (<=0.7.1)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"]
[[package]] [[package]]
name = "zipp" name = "urllib3"
version = "3.20.2" version = "1.25.9"
description = "Backport of pathlib-compatible object wrapper for zip files" description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
files = [
{file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"},
{file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"},
]
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] brotli = ["brotlipy (>=0.6.0)"]
cover = ["pytest-cov"] secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
enabler = ["pytest-enabler (>=2.2)"]
test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] [[package]]
type = ["pytest-mypy"] name = "xlrd"
version = "1.2.0"
description = "Library for developers to extract data from Microsoft Excel (tm) spreadsheet files"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[metadata] [metadata]
lock-version = "2.0" lock-version = "1.1"
python-versions = ">=3.8,<3.14" python-versions = "^3.8"
content-hash = "6db8fff0987f3dadb02cbf0e510a2d04b01ab2dc6d7b0fb32a0e33a8d30b3a58" content-hash = "b3d607363c6daf2b5448aa5ee676cff28606af6200d8e9b42e89937a190a3d46"
[metadata.files]
altgraph = [
{file = "altgraph-0.17.2-py2.py3-none-any.whl", hash = "sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857"},
{file = "altgraph-0.17.2.tar.gz", hash = "sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158"},
]
certifi = [
{file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"},
{file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"},
]
chardet = [
{file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"},
{file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"},
]
dis3 = [
{file = "dis3-0.1.3-py2-none-any.whl", hash = "sha256:61f7720dd0d8749d23fda3d7227ce74d73da11c2fade993a67ab2f9852451b14"},
{file = "dis3-0.1.3-py3-none-any.whl", hash = "sha256:30b6412d33d738663e8ded781b138f4b01116437f0872aa56aa3adba6aeff218"},
{file = "dis3-0.1.3.tar.gz", hash = "sha256:9259b881fc1df02ed12ac25f82d4a85b44241854330b1a651e40e0c675cb2d1e"},
]
docutils = [
{file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"},
{file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"},
]
future = [
{file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
]
idna = [
{file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"},
{file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"},
]
itsdangerous = [
{file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"},
{file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"},
]
kivy = [
{file = "Kivy-1.11.1-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:11e85eaf6efbfa2362a3334ffdad179a1b0ca8d255cca79eaa6a2765560d4982"},
{file = "Kivy-1.11.1-cp27-cp27m-win32.whl", hash = "sha256:5c3d0f2749522d62e9cce09cd54b2d823bf1b6b644ff1f627be49de6f3e3cba0"},
{file = "Kivy-1.11.1-cp27-cp27m-win_amd64.whl", hash = "sha256:f835462dd9aa491272552ef079b948a088598e2e95d68bb1d885d2c3f3d4e2c3"},
{file = "Kivy-1.11.1-cp35-cp35m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:090d3ded9835a17477cd93fbdaf0a7c42ff2218981cf198ded5ad8795bc74391"},
{file = "Kivy-1.11.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:b85ccf165050cbf2ee8447671eebbc222b369b40f0e0038dd9547d49a5e37373"},
{file = "Kivy-1.11.1-cp35-cp35m-win32.whl", hash = "sha256:4a5480cbf837d3780c77a4f61b32b56d22ae9f03845e7a89dd3eaef1ae5fd037"},
{file = "Kivy-1.11.1-cp35-cp35m-win_amd64.whl", hash = "sha256:a687602d90c4629dd036f577ca39acb76ba581370f9d915f3cab99be818ba8ad"},
{file = "Kivy-1.11.1-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:c36652caa7f6c327dee834cfc699d5962d346b7a53e54bd81abc17c314226d89"},
{file = "Kivy-1.11.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:b7ef6aad43a86d8df3fb865db864e354f2155a748019f8517f69f65c1a29cb64"},
{file = "Kivy-1.11.1-cp36-cp36m-win32.whl", hash = "sha256:f3bea6e4a21991827885d04127fc6d09a0e974ecfa12da7bf5faae93562ea102"},
{file = "Kivy-1.11.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ece170514db3f49844a41e4c910ad9ce9bc46da6f47a49158e11266bdcc6e479"},
{file = "Kivy-1.11.1-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:8819a27a09871af451760cb69486ced52e830c8a0a37480f22ef5e692f12c05b"},
{file = "Kivy-1.11.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:1a1ff32f8a95f1e175198cbab81fcd2596783b180d4eafe63e87d171aa7fdb5e"},
{file = "Kivy-1.11.1-cp37-cp37m-win32.whl", hash = "sha256:815a5c0b3b72fcd81ca7b2aa0744087163ed03e4cf9ab4e7c9733cea99fc1571"},
{file = "Kivy-1.11.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1d28b198a64c30db8d94a0488e85f3037af60d514ab0d7ad5ab45add3ab77090"},
{file = "Kivy-1.11.1.tar.gz", hash = "sha256:4d0e596f74271e901b551f77661dde238df4765484fce9f5d1c72e8022984e84"},
]
"kivy-deps.angle" = [
{file = "kivy_deps.angle-0.3.0-cp310-cp310-win32.whl", hash = "sha256:7b56477c726e361592f794d49b2fdd96d579b7efd7225a8aadf7fd01d4e8cb80"},
{file = "kivy_deps.angle-0.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:a4b78fd9d47c76e5ff52fcbaa040920a2f97bff038f4c534346dd833dc8f3145"},
{file = "kivy_deps.angle-0.3.0-cp36-cp36m-win32.whl", hash = "sha256:a2cea09e8a5e899629466403fbd540459f1cdef8d08c6c479b6607b95309be02"},
{file = "kivy_deps.angle-0.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:b167e19b3eea55a9a8c606a607bb909ec1bedda88deee40347c780b310155a79"},
{file = "kivy_deps.angle-0.3.0-cp37-cp37m-win32.whl", hash = "sha256:d0e7b7b9eb9669837a5d70808a7ea45f2b61961b56f9f69a233bad6bd36ce260"},
{file = "kivy_deps.angle-0.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b9d07976b0bf6bac724a42aa8ed5a8c7caa95609046db30c8f15bb731f8e4d36"},
{file = "kivy_deps.angle-0.3.0-cp38-cp38-win32.whl", hash = "sha256:99c40d53582a958748e251dfbd61aa67fb85963e27529ca08a21f2f5eeed04e1"},
{file = "kivy_deps.angle-0.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:50605fdd4c9fdbe9f717069734a598a9aba0afe5d3f0412afbe2ecff0326e92d"},
{file = "kivy_deps.angle-0.3.0-cp39-cp39-win32.whl", hash = "sha256:64ac7f33c000585dc30194e604aed925972c6b7c3848b5c3b073ae916fb0b55c"},
{file = "kivy_deps.angle-0.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb4d53f15a093214adbbe205c108ede5cc0f6af6eff104c1b8c468ddaaf6400a"},
]
"kivy-deps.glew" = [
{file = "kivy_deps.glew-0.1.12-cp27-cp27m-win32.whl", hash = "sha256:92e72fa2c425887987d1aa861c99537033dc20d68ae1c54864871f0401682586"},
{file = "kivy_deps.glew-0.1.12-cp27-cp27m-win_amd64.whl", hash = "sha256:c843104690c0c8f3a58105c53c57f31506f6f90562c18de00bd19317cc1045a7"},
{file = "kivy_deps.glew-0.1.12-cp35-cp35m-win32.whl", hash = "sha256:ee8ab67abb2c98d84feede657cae472e7723e529af07394244bdd33caafb1a38"},
{file = "kivy_deps.glew-0.1.12-cp35-cp35m-win_amd64.whl", hash = "sha256:ab81783a82bef88a8d2bcf8a93bc21df6b8b0db6ee551eb802727d18f9074b17"},
{file = "kivy_deps.glew-0.1.12-cp36-cp36m-win32.whl", hash = "sha256:45aa7f0e8d9bcf5fc1810c9c38bc20edf7dee61df81ecf62102e0f84153f924a"},
{file = "kivy_deps.glew-0.1.12-cp36-cp36m-win_amd64.whl", hash = "sha256:ef1116d99bd9cc737cb8c0e13e676955c17d6e4d6d1af5cfccef089a430071bb"},
{file = "kivy_deps.glew-0.1.12-cp37-cp37m-win32.whl", hash = "sha256:1e28e40017af9d081fc0fc95b4fadaf31d15e9f63478dcee1c4257d67079894e"},
{file = "kivy_deps.glew-0.1.12-cp37-cp37m-win_amd64.whl", hash = "sha256:6bb435620c3187d2c61054adb9ec277ed487256b457a0a7b1491bc0cb7247e18"},
{file = "kivy_deps.glew-0.1.12-cp38-cp38-win32.whl", hash = "sha256:09f72ee5ef33ff273332e2a229dc97d650d29818a0189339421949e4e0f63d93"},
{file = "kivy_deps.glew-0.1.12-cp38-cp38-win_amd64.whl", hash = "sha256:cf351aad171796f8051af8e49ec430a9aa128d8557d8643e73f2bb1e5f9c2dab"},
]
"kivy-deps.gstreamer" = [
{file = "kivy_deps.gstreamer-0.1.17-cp27-cp27m-win32.whl", hash = "sha256:309eca64dee5939f16f8465e5cbb08bdde7c90ded1af6a00690c7e928326af79"},
{file = "kivy_deps.gstreamer-0.1.17-cp27-cp27m-win_amd64.whl", hash = "sha256:0d9598d2d31c0e780adf4b767fa3a691123621fd0ffef94b83cf82c2da84341b"},
{file = "kivy_deps.gstreamer-0.1.17-cp35-cp35m-win32.whl", hash = "sha256:4f2ddd61d185310258d338ae80a646df7822efdd7d67e57f49dc7b87555c5d7e"},
{file = "kivy_deps.gstreamer-0.1.17-cp35-cp35m-win_amd64.whl", hash = "sha256:6fa9f76afe600baa221abee31ce7dc63e653d0affe0f6c558bfc4f35af96396f"},
{file = "kivy_deps.gstreamer-0.1.17-cp36-cp36m-win32.whl", hash = "sha256:c4709765e2b17c6c96b46a92207b0457def147544d825654077603eaf0d424de"},
{file = "kivy_deps.gstreamer-0.1.17-cp36-cp36m-win_amd64.whl", hash = "sha256:c29cfc63fe70a58dad889e631f1ba4711c9ea80103f2b2b8d670a97f093076c8"},
{file = "kivy_deps.gstreamer-0.1.17-cp37-cp37m-win32.whl", hash = "sha256:4d996377111e854b3dea90846f9b2f98766a44529fd8b72125e18c552381d928"},
{file = "kivy_deps.gstreamer-0.1.17-cp37-cp37m-win_amd64.whl", hash = "sha256:739cd331b9f33a822d700273674a79a3157054e9358a01a0d553f094a5f4a8c9"},
{file = "kivy_deps.gstreamer-0.1.17-cp38-cp38-win_amd64.whl", hash = "sha256:3d53d2c84c0a997c4cac6c239b1e0a6486e533836321003dc365ec42b97a664b"},
]
"kivy-deps.sdl2" = [
{file = "kivy_deps.sdl2-0.1.22-cp27-cp27m-win32.whl", hash = "sha256:1b987bdd4fbbcb31baf0d7fc9584ad99912179b8968311bb7e30fbeb14e98e0d"},
{file = "kivy_deps.sdl2-0.1.22-cp27-cp27m-win_amd64.whl", hash = "sha256:228128cdd8112dc7505ac43027a770476e9ef282e0b84ca68037133cd025960b"},
{file = "kivy_deps.sdl2-0.1.22-cp35-cp35m-win32.whl", hash = "sha256:053f26e8c05d5545bdbc7eeb8c450b8e4410ee355792e9345af536110fe247e2"},
{file = "kivy_deps.sdl2-0.1.22-cp35-cp35m-win_amd64.whl", hash = "sha256:5ce23f1a3286d6288751a12b0eaefd02f947ea101bb807e9781b964e496fc3f3"},
{file = "kivy_deps.sdl2-0.1.22-cp36-cp36m-win32.whl", hash = "sha256:96e1fa89fd8b5351f2d3c26bbffd50df8d554b03fba4025ecc941d773d241698"},
{file = "kivy_deps.sdl2-0.1.22-cp36-cp36m-win_amd64.whl", hash = "sha256:c3ace0ddde0e59cdcaf260eda1daa0c05ca9bf8cd0c4ea404539de25a5dcaec7"},
{file = "kivy_deps.sdl2-0.1.22-cp37-cp37m-win32.whl", hash = "sha256:7928746eaed51944c10d1bb36fcefebe3d1aff1b97ba32359c2c97ba74707e1b"},
{file = "kivy_deps.sdl2-0.1.22-cp37-cp37m-win_amd64.whl", hash = "sha256:2c2fd5a12a7a9afe3bb962b273561099a180edae91bb9c8f8386b72253fcae4a"},
{file = "kivy_deps.sdl2-0.1.22-cp38-cp38-win32.whl", hash = "sha256:9270fa8ed5130074b167a7a3a9c85efc3cfe3c04584ab084cb6ae9e4edfa8168"},
{file = "kivy_deps.sdl2-0.1.22-cp38-cp38-win_amd64.whl", hash = "sha256:92ed97d3247bc8ce98f336cbc940bb889310199326e9ccf251c49ae7e4b80de8"},
]
kivy-garden = [
{file = "Kivy Garden-0.1.4.tar.gz", hash = "sha256:9b7d9de5efacbcd0c4b3dd873b30622a86093c9965aa47b523c7a32f3eb34610"},
{file = "kivy-garden-0.1.4.tar.gz", hash = "sha256:c256f42788421273a08fbb0a228f0fb0e80dd86b629fb8c0920507f645be6c72"},
]
packaging = [
{file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"},
{file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"},
]
pdf2image = [
{file = "pdf2image-1.12.1.tar.gz", hash = "sha256:a0d9906f5507192210a8d5d7ead63145e9dec4bccc4564b1fb644e923913c31c"},
]
pefile = [
{file = "pefile-2021.9.3.tar.gz", hash = "sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a"},
]
pillow = [
{file = "Pillow-7.2.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:1ca594126d3c4def54babee699c055a913efb01e106c309fa6b04405d474d5ae"},
{file = "Pillow-7.2.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c92302a33138409e8f1ad16731568c55c9053eee71bb05b6b744067e1b62380f"},
{file = "Pillow-7.2.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8dad18b69f710bf3a001d2bf3afab7c432785d94fcf819c16b5207b1cfd17d38"},
{file = "Pillow-7.2.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:431b15cffbf949e89df2f7b48528be18b78bfa5177cb3036284a5508159492b5"},
{file = "Pillow-7.2.0-cp35-cp35m-win32.whl", hash = "sha256:09d7f9e64289cb40c2c8d7ad674b2ed6105f55dc3b09aa8e4918e20a0311e7ad"},
{file = "Pillow-7.2.0-cp35-cp35m-win_amd64.whl", hash = "sha256:0295442429645fa16d05bd567ef5cff178482439c9aad0411d3f0ce9b88b3a6f"},
{file = "Pillow-7.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:ec29604081f10f16a7aea809ad42e27764188fc258b02259a03a8ff7ded3808d"},
{file = "Pillow-7.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:612cfda94e9c8346f239bf1a4b082fdd5c8143cf82d685ba2dba76e7adeeb233"},
{file = "Pillow-7.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0a80dd307a5d8440b0a08bd7b81617e04d870e40a3e46a32d9c246e54705e86f"},
{file = "Pillow-7.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:06aba4169e78c439d528fdeb34762c3b61a70813527a2c57f0540541e9f433a8"},
{file = "Pillow-7.2.0-cp36-cp36m-win32.whl", hash = "sha256:f7e30c27477dffc3e85c2463b3e649f751789e0f6c8456099eea7ddd53be4a8a"},
{file = "Pillow-7.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:ffe538682dc19cc542ae7c3e504fdf54ca7f86fb8a135e59dd6bc8627eae6cce"},
{file = "Pillow-7.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:94cf49723928eb6070a892cb39d6c156f7b5a2db4e8971cb958f7b6b104fb4c4"},
{file = "Pillow-7.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6edb5446f44d901e8683ffb25ebdfc26988ee813da3bf91e12252b57ac163727"},
{file = "Pillow-7.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:52125833b070791fcb5710fabc640fc1df07d087fc0c0f02d3661f76c23c5b8b"},
{file = "Pillow-7.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9ad7f865eebde135d526bb3163d0b23ffff365cf87e767c649550964ad72785d"},
{file = "Pillow-7.2.0-cp37-cp37m-win32.whl", hash = "sha256:c79f9c5fb846285f943aafeafda3358992d64f0ef58566e23484132ecd8d7d63"},
{file = "Pillow-7.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d350f0f2c2421e65fbc62690f26b59b0bcda1b614beb318c81e38647e0f673a1"},
{file = "Pillow-7.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:6d7741e65835716ceea0fd13a7d0192961212fd59e741a46bbed7a473c634ed6"},
{file = "Pillow-7.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:edf31f1150778abd4322444c393ab9c7bd2af271dd4dafb4208fb613b1f3cdc9"},
{file = "Pillow-7.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:d08b23fdb388c0715990cbc06866db554e1822c4bdcf6d4166cf30ac82df8c41"},
{file = "Pillow-7.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:5e51ee2b8114def244384eda1c82b10e307ad9778dac5c83fb0943775a653cd8"},
{file = "Pillow-7.2.0-cp38-cp38-win32.whl", hash = "sha256:725aa6cfc66ce2857d585f06e9519a1cc0ef6d13f186ff3447ab6dff0a09bc7f"},
{file = "Pillow-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:a060cf8aa332052df2158e5a119303965be92c3da6f2d93b6878f0ebca80b2f6"},
{file = "Pillow-7.2.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:9c87ef410a58dd54b92424ffd7e28fd2ec65d2f7fc02b76f5e9b2067e355ebf6"},
{file = "Pillow-7.2.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:e901964262a56d9ea3c2693df68bc9860b8bdda2b04768821e4c44ae797de117"},
{file = "Pillow-7.2.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:25930fadde8019f374400f7986e8404c8b781ce519da27792cbe46eabec00c4d"},
{file = "Pillow-7.2.0.tar.gz", hash = "sha256:97f9e7953a77d5a70f49b9a48da7776dc51e9b738151b22dacf101641594a626"},
]
pygments = [
{file = "Pygments-2.6.1-py3-none-any.whl", hash = "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"},
{file = "Pygments-2.6.1.tar.gz", hash = "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"},
]
pyinstaller = [
{file = "PyInstaller-3.6.tar.gz", hash = "sha256:3730fa80d088f8bb7084d32480eb87cbb4ddb64123363763cf8f2a1378c1c4b7"},
]
pyparsing = [
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
]
pywin32-ctypes = [
{file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"},
{file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"},
]
requests = [
{file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"},
{file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"},
]
urllib3 = [
{file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"},
{file = "urllib3-1.25.9.tar.gz", hash = "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"},
]
xlrd = [
{file = "xlrd-1.2.0-py2.py3-none-any.whl", hash = "sha256:e551fb498759fa3a5384a94ccd4c3c02eb7c00ea424426e212ac0c57be9dfbde"},
{file = "xlrd-1.2.0.tar.gz", hash = "sha256:546eb36cee8db40c3eaa46c351e67ffee6eeb5fa2650b71bc4c758a29a1b29b2"},
]

View File

@ -5,10 +5,8 @@ description = ""
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.8,<3.14" python = "^3.8"
flake8 = "^4.0.1" flake8 = "^4.0.1"
pyinstaller = "6.10.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]

View File

@ -1,94 +1,4 @@
[ [
{
"pypy_version": "7.3.8rc2",
"python_version": "3.8.12",
"stable": false,
"latest_pypy": false,
"date": "2022-02-11",
"files": [
{
"filename": "pypy3.8-v7.3.8rc2-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-linux32.tar.bz2"
},
{
"filename": "pypy3.8-v7.3.8rc2-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-linux64.tar.bz2"
},
{
"filename": "pypy3.8-v7.3.8rc2-darwin64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-darwin64.tar.bz2"
},
{
"filename": "pypy3.8-v7.3.8rc2-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-s390x.tar.bz2"
},
{
"filename": "pypy3.8-v7.3.8rc2-win64.zip",
"arch": "x64",
"platform": "win64",
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-win64.zip"
},
{
"filename": "pypy3.8-v7.3.8rc2-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-win32.zip"
}
]
},
{
"pypy_version": "7.4.0rc1",
"python_version": "3.6.12",
"stable": false,
"latest_pypy": false,
"date": "2021-11-11",
"files": [
{
"filename": "pypy3.6-v7.4.0rc1-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-aarch64.tar.bz2"
},
{
"filename": "pypy3.6-v7.4.0rc1-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-linux32.tar.bz2"
},
{
"filename": "pypy3.6-v7.4.0rc1-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-linux64.tar.bz2"
},
{
"filename": "pypy3.6-v7.4.0rc1-darwin64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-darwin64.tar.bz2"
},
{
"filename": "pypy3.6-v7.4.0rc1-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-win32.zip"
},
{
"filename": "pypy3.6-v7.4.0rc1-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-s390x.tar.bz2"
}
]
},
{ {
"pypy_version": "7.3.3", "pypy_version": "7.3.3",
"python_version": "3.6.12", "python_version": "3.6.12",

View File

@ -7,6 +7,6 @@ Kivy-Garden==0.1.4
packaging==20.7 packaging==20.7
pdf2image==1.12.1 pdf2image==1.12.1
Pygments==2.6.1 Pygments==2.6.1
requests==2.32.2 requests==2.24.0
urllib3==1.26.19 urllib3==1.25.10
xlrd==1.2.0 xlrd==1.2.0

View File

@ -30,18 +30,18 @@ pdf2image==1.12.1
pefile==2021.9.3; python_full_version >= '3.6.0' pefile==2021.9.3; python_full_version >= '3.6.0'
pillow>=10.2.0 pillow==7.2
pygments==2.6.1 pygments==2.6.1
pyinstaller==6.10.0 pyinstaller==3.6
pyparsing==2.4.7; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2' pyparsing==2.4.7; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'
pywin32-ctypes==0.2.0 pywin32-ctypes==0.2.0
requests==2.32.2 requests==2.24.0
urllib3==1.26.19 urllib3==1.25.9
xlrd==1.2.0 xlrd==1.2.0

View File

@ -1,29 +1,4 @@
[ [
{
"version": "1.2.4-beta.2",
"stable": false,
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5",
"files": [
{
"filename": "sometool-1.2.4-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-linux-x64.tar.gz"
},
{
"filename": "sometool-1.2.4-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-darwin-x64.tar.gz"
},
{
"filename": "sometool-1.2.4-win32-x64.tar.gz",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-win32-x64.tar.gz"
}
]
},
{ {
"version": "1.2.3", "version": "1.2.3",
"stable": true, "stable": true,
@ -50,27 +25,27 @@
] ]
}, },
{ {
"version": "1.1.0-beta.2", "version": "1.2.3-beta.2",
"stable": false, "stable": false,
"release_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5", "release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5",
"files": [ "files": [
{ {
"filename": "sometool-1.1.0-linux-x64.tar.gz", "filename": "sometool-1.2.3-linux-x64.tar.gz",
"arch": "x64", "arch": "x64",
"platform": "linux", "platform": "linux",
"download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-linux-x64.tar.gz" "download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5/sometool-1.2.3-linux-x64.tar.gz"
}, },
{ {
"filename": "sometool-1.1.0-darwin-x64.tar.gz", "filename": "sometool-1.2.3-darwin-x64.tar.gz",
"arch": "x64", "arch": "x64",
"platform": "darwin", "platform": "darwin",
"download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-darwin-x64.tar.gz" "download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-darwin-x64.tar.gz"
}, },
{ {
"filename": "sometool-1.1.0-win32-x64.tar.gz", "filename": "sometool-1.2.3-win32-x64.tar.gz",
"arch": "x64", "arch": "x64",
"platform": "win32", "platform": "win32",
"download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-win32-x64.tar.gz" "download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-win32-x64.tar.gz"
} }
] ]
} }

View File

@ -1,378 +0,0 @@
import fs from 'fs';
import {HttpClient} from '@actions/http-client';
import * as ifm from '@actions/http-client/lib/interfaces';
import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec';
import * as core from '@actions/core';
import * as path from 'path';
import * as semver from 'semver';
import * as finder from '../src/find-graalpy';
import {IGraalPyManifestRelease, IS_WINDOWS} from '../src/utils';
import manifestData from './data/graalpy.json';
const architecture = 'x64';
const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp');
/* GraalPy doesn't have a windows release yet */
const describeSkipOnWindows = IS_WINDOWS ? describe.skip : describe;
describe('parseGraalPyVersion', () => {
it.each([
['graalpy-23', '23'],
['graalpy-23.0', '23.0'],
['graalpy23.0', '23.0']
])('%s -> %s', (input, expected) => {
expect(finder.parseGraalPyVersion(input)).toEqual(expected);
});
it.each(['', 'graalpy-', 'graalpy', 'p', 'notgraalpy-'])(
'throw on invalid input "%s"',
input => {
expect(() => finder.parseGraalPyVersion(input)).toThrow(
"Invalid 'version' property for GraalPy. GraalPy version should be specified as 'graalpy<python-version>' or 'graalpy-<python-version>'. See README for examples and documentation."
);
}
);
});
describe('findGraalPyToolCache', () => {
const actualGraalPyVersion = '23.0.0';
const graalpyPath = path.join('GraalPy', actualGraalPyVersion, architecture);
let tcFind: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance;
let addPathSpy: jest.SpyInstance;
let exportVariableSpy: jest.SpyInstance;
let setOutputSpy: jest.SpyInstance;
beforeEach(() => {
tcFind = jest.spyOn(tc, 'find');
tcFind.mockImplementation((toolname: string, pythonVersion: string) => {
const semverVersion = new semver.Range(pythonVersion);
return semver.satisfies(actualGraalPyVersion, semverVersion)
? graalpyPath
: '';
});
infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => null);
warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null);
debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null);
addPathSpy = jest.spyOn(core, 'addPath');
addPathSpy.mockImplementation(() => null);
exportVariableSpy = jest.spyOn(core, 'exportVariable');
exportVariableSpy.mockImplementation(() => null);
setOutputSpy = jest.spyOn(core, 'setOutput');
setOutputSpy.mockImplementation(() => null);
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it('GraalPy exists on the path and versions are satisfied', () => {
expect(finder.findGraalPyToolCache('23.0.0', architecture)).toEqual({
installDir: graalpyPath,
resolvedGraalPyVersion: actualGraalPyVersion
});
});
it('GraalPy exists on the path and versions are satisfied with semver', () => {
expect(finder.findGraalPyToolCache('23.0', architecture)).toEqual({
installDir: graalpyPath,
resolvedGraalPyVersion: actualGraalPyVersion
});
});
it("GraalPy exists on the path, but version doesn't match", () => {
expect(finder.findGraalPyToolCache('22.3', architecture)).toEqual({
installDir: '',
resolvedGraalPyVersion: ''
});
});
});
describeSkipOnWindows('findGraalPyVersion', () => {
let getBooleanInputSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
let addPathSpy: jest.SpyInstance;
let exportVariableSpy: jest.SpyInstance;
let setOutputSpy: jest.SpyInstance;
let tcFind: jest.SpyInstance;
let spyExtractZip: jest.SpyInstance;
let spyExtractTar: jest.SpyInstance;
let spyHttpClient: jest.SpyInstance;
let spyExistsSync: jest.SpyInstance;
let spyExec: jest.SpyInstance;
let spySymlinkSync: jest.SpyInstance;
let spyDownloadTool: jest.SpyInstance;
let spyFsReadDir: jest.SpyInstance;
let spyCacheDir: jest.SpyInstance;
let spyChmodSync: jest.SpyInstance;
let spyCoreAddPath: jest.SpyInstance;
let spyCoreExportVariable: jest.SpyInstance;
const env = process.env;
beforeEach(() => {
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(() => false);
infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {});
warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null);
debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null);
addPathSpy = jest.spyOn(core, 'addPath');
addPathSpy.mockImplementation(() => null);
exportVariableSpy = jest.spyOn(core, 'exportVariable');
exportVariableSpy.mockImplementation(() => null);
setOutputSpy = jest.spyOn(core, 'setOutput');
setOutputSpy.mockImplementation(() => null);
jest.resetModules();
process.env = {...env};
tcFind = jest.spyOn(tc, 'find');
tcFind.mockImplementation((tool: string, version: string) => {
const semverRange = new semver.Range(version);
let graalpyPath = '';
if (semver.satisfies('23.0.0', semverRange)) {
graalpyPath = path.join(toolDir, 'GraalPy', '23.0.0', architecture);
}
return graalpyPath;
});
spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'GraalPy'));
spyExtractZip = jest.spyOn(tc, 'extractZip');
spyExtractZip.mockImplementation(() => tempDir);
spyExtractTar = jest.spyOn(tc, 'extractTar');
spyExtractTar.mockImplementation(() => tempDir);
spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation((directory: string) => ['GraalPyTest']);
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation(
async (): Promise<ifm.TypedResponse<IGraalPyManifestRelease[]>> => {
const result = JSON.stringify(manifestData);
return {
statusCode: 200,
headers: {},
result: JSON.parse(result) as IGraalPyManifestRelease[]
};
}
);
spyExec = jest.spyOn(exec, 'exec');
spyExec.mockImplementation(() => undefined);
spySymlinkSync = jest.spyOn(fs, 'symlinkSync');
spySymlinkSync.mockImplementation(() => undefined);
spyExistsSync = jest.spyOn(fs, 'existsSync');
spyExistsSync.mockReturnValue(true);
spyCoreAddPath = jest.spyOn(core, 'addPath');
spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
process.env = env;
});
it('found GraalPy in toolcache', async () => {
await expect(
finder.findGraalPyVersion(
'graalpy-23.0',
architecture,
true,
false,
false
)
).resolves.toEqual('23.0.0');
expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation',
expect.anything()
);
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'PKG_CONFIG_PATH',
expect.anything()
);
});
it('throw on invalid input format', async () => {
await expect(
finder.findGraalPyVersion('graalpy-x23', architecture, true, false, false)
).rejects.toThrow();
});
it('found and install successfully', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.0.0', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findGraalPyVersion(
'graalpy-23.0.0',
architecture,
true,
false,
false
)
).resolves.toEqual('23.0.0');
expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation',
expect.anything()
);
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'PKG_CONFIG_PATH',
expect.anything()
);
});
it('found and install successfully without environment update', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.0.0', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findGraalPyVersion(
'graalpy-23.0.0',
architecture,
false,
false,
false
)
).resolves.toEqual('23.0.0');
expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled();
});
it('throw if release is not found', async () => {
await expect(
finder.findGraalPyVersion(
'graalpy-19.0.0',
architecture,
true,
false,
false
)
).rejects.toThrow(
`GraalPy version 19.0.0 with arch ${architecture} not found`
);
});
it('check-latest enabled version found and used from toolcache', async () => {
await expect(
finder.findGraalPyVersion(
'graalpy-23.0.0',
architecture,
false,
true,
false
)
).resolves.toEqual('23.0.0');
expect(infoSpy).toHaveBeenCalledWith('Resolved as GraalPy 23.0.0');
});
it('check-latest enabled version found and install successfully', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.0.0', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findGraalPyVersion(
'graalpy-23.0.0',
architecture,
false,
true,
false
)
).resolves.toEqual('23.0.0');
expect(infoSpy).toHaveBeenCalledWith('Resolved as GraalPy 23.0.0');
});
it('check-latest enabled version is not found and used from toolcache', async () => {
tcFind.mockImplementationOnce((tool: string, version: string) => {
const semverRange = new semver.Range(version);
let graalpyPath = '';
if (semver.satisfies('22.3.4', semverRange)) {
graalpyPath = path.join(toolDir, 'GraalPy', '22.3.4', architecture);
}
return graalpyPath;
});
await expect(
finder.findGraalPyVersion(
'graalpy-22.3.4',
architecture,
false,
true,
false
)
).resolves.toEqual('22.3.4');
expect(infoSpy).toHaveBeenCalledWith(
'Failed to resolve GraalPy 22.3.4 from manifest'
);
});
it('found and install successfully, pre-release fallback', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.1', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findGraalPyVersion(
'graalpy23.1',
architecture,
false,
false,
false
)
).rejects.toThrow();
await expect(
finder.findGraalPyVersion('graalpy23.1', architecture, false, false, true)
).resolves.toEqual('23.1.0-a.1');
});
});

View File

@ -2,7 +2,7 @@ import fs from 'fs';
import * as utils from '../src/utils'; import * as utils from '../src/utils';
import {HttpClient} from '@actions/http-client'; import {HttpClient} from '@actions/http-client';
import * as ifm from '@actions/http-client/lib/interfaces'; import * as ifm from '@actions/http-client/interfaces';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import * as core from '@actions/core'; import * as core from '@actions/core';
@ -17,7 +17,7 @@ import {
getPyPyVersionFromPath getPyPyVersionFromPath
} from '../src/utils'; } from '../src/utils';
import manifestData from './data/pypy.json'; const manifestData = require('./data/pypy.json');
let architecture: string; let architecture: string;
@ -51,7 +51,7 @@ describe('parsePyPyVersion', () => {
it.each(['', 'pypy-', 'pypy', 'p', 'notpypy-'])( it.each(['', 'pypy-', 'pypy', 'p', 'notpypy-'])(
'throw on invalid input "%s"', 'throw on invalid input "%s"',
input => { input => {
expect(() => finder.parsePyPyVersion(input)).toThrow( expect(() => finder.parsePyPyVersion(input)).toThrowError(
"Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy<python-version>' or 'pypy-<python-version>'. See README for examples and documentation." "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy<python-version>' or 'pypy-<python-version>'. See README for examples and documentation."
); );
} }
@ -60,7 +60,7 @@ describe('parsePyPyVersion', () => {
it.each(['pypy-2', 'pypy-3', 'pypy2', 'pypy3', 'pypy3.x', 'pypy3.8.10'])( it.each(['pypy-2', 'pypy-3', 'pypy2', 'pypy3', 'pypy3.x', 'pypy3.8.10'])(
'throw on invalid input "%s"', 'throw on invalid input "%s"',
input => { input => {
expect(() => finder.parsePyPyVersion(input)).toThrow( expect(() => finder.parsePyPyVersion(input)).toThrowError(
"Invalid format of Python version for PyPy. Python version should be specified in format 'x.y'. See README for examples and documentation." "Invalid format of Python version for PyPy. Python version should be specified in format 'x.y'. See README for examples and documentation."
); );
} }
@ -240,7 +240,7 @@ describe('findPyPyVersion', () => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation( spyHttpClient.mockImplementation(
async (): Promise<ifm.TypedResponse<IPyPyManifestRelease[]>> => { async (): Promise<ifm.ITypedResponse<IPyPyManifestRelease[]>> => {
const result = JSON.stringify(manifestData); const result = JSON.stringify(manifestData);
return { return {
statusCode: 200, statusCode: 200,
@ -273,13 +273,7 @@ describe('findPyPyVersion', () => {
it('found PyPy in toolcache', async () => { it('found PyPy in toolcache', async () => {
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true, false)
'pypy-3.6-v7.3.x',
architecture,
true,
false,
false
)
).resolves.toEqual({ ).resolves.toEqual({
resolvedPythonVersion: '3.6.12', resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.3.3' resolvedPyPyVersion: '7.3.3'
@ -297,13 +291,13 @@ describe('findPyPyVersion', () => {
it('throw on invalid input format', async () => { it('throw on invalid input format', async () => {
await expect( await expect(
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false) finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false)
).rejects.toThrow(); ).rejects.toThrow();
}); });
it('throw on invalid input format pypy3.7-7.3.x', async () => { it('throw on invalid input format pypy3.7-7.3.x', async () => {
await expect( await expect(
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false) finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false)
).rejects.toThrow(); ).rejects.toThrow();
}); });
@ -315,13 +309,7 @@ describe('findPyPyVersion', () => {
spyChmodSync = jest.spyOn(fs, 'chmodSync'); spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, true, false)
'pypy-3.7-v7.3.x',
architecture,
true,
false,
false
)
).resolves.toEqual({ ).resolves.toEqual({
resolvedPythonVersion: '3.7.9', resolvedPythonVersion: '3.7.9',
resolvedPyPyVersion: '7.3.3' resolvedPyPyVersion: '7.3.3'
@ -345,13 +333,7 @@ describe('findPyPyVersion', () => {
spyChmodSync = jest.spyOn(fs, 'chmodSync'); spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, false)
'pypy-3.7-v7.3.x',
architecture,
false,
false,
false
)
).resolves.toEqual({ ).resolves.toEqual({
resolvedPythonVersion: '3.7.9', resolvedPythonVersion: '3.7.9',
resolvedPyPyVersion: '7.3.3' resolvedPyPyVersion: '7.3.3'
@ -362,27 +344,15 @@ describe('findPyPyVersion', () => {
it('throw if release is not found', async () => { it('throw if release is not found', async () => {
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true, false)
'pypy-3.7-v7.5.x', ).rejects.toThrowError(
architecture,
true,
false,
false
)
).rejects.toThrow(
`PyPy version 3.7 (v7.5.x) with arch ${architecture} not found` `PyPy version 3.7 (v7.5.x) with arch ${architecture} not found`
); );
}); });
it('check-latest enabled version found and used from toolcache', async () => { it('check-latest enabled version found and used from toolcache', async () => {
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, false, true)
'pypy-3.6-v7.3.x',
architecture,
false,
true,
false
)
).resolves.toEqual({ ).resolves.toEqual({
resolvedPythonVersion: '3.6.12', resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.3.3' resolvedPyPyVersion: '7.3.3'
@ -401,13 +371,7 @@ describe('findPyPyVersion', () => {
spyChmodSync = jest.spyOn(fs, 'chmodSync'); spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, true)
'pypy-3.7-v7.3.x',
architecture,
false,
true,
false
)
).resolves.toEqual({ ).resolves.toEqual({
resolvedPythonVersion: '3.7.9', resolvedPythonVersion: '3.7.9',
resolvedPyPyVersion: '7.3.3' resolvedPyPyVersion: '7.3.3'
@ -427,13 +391,7 @@ describe('findPyPyVersion', () => {
return pypyPath; return pypyPath;
}); });
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion('pypy-3.8-v7.3.x', architecture, false, true)
'pypy-3.8-v7.3.x',
architecture,
false,
true,
false
)
).resolves.toEqual({ ).resolves.toEqual({
resolvedPythonVersion: '3.8.8', resolvedPythonVersion: '3.8.8',
resolvedPyPyVersion: '7.3.3' resolvedPyPyVersion: '7.3.3'
@ -443,22 +401,4 @@ describe('findPyPyVersion', () => {
'Failed to resolve PyPy v7.3.x with Python (3.8) from manifest' 'Failed to resolve PyPy v7.3.x with Python (3.8) from manifest'
); );
}); });
it('found and install successfully, pre-release fallback', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.8.12', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findPyPyVersion('pypy3.8', architecture, false, false, false)
).rejects.toThrow();
await expect(
finder.findPyPyVersion('pypy3.8', architecture, false, false, true)
).resolves.toEqual({
resolvedPythonVersion: '3.8.12',
resolvedPyPyVersion: '7.3.8rc2'
});
});
}); });

View File

@ -1,43 +0,0 @@
import {desugarVersion, pythonVersionToSemantic} from '../src/find-python';
describe('desugarVersion', () => {
it.each([
['3.13', {version: '3.13', freethreaded: false}],
['3.13t', {version: '3.13', freethreaded: true}],
['3.13.1', {version: '3.13.1', freethreaded: false}],
['3.13.1t', {version: '3.13.1', freethreaded: true}],
['3.14-dev', {version: '~3.14.0-0', freethreaded: false}],
['3.14t-dev', {version: '~3.14.0-0', freethreaded: true}]
])('%s -> %s', (input, expected) => {
expect(desugarVersion(input)).toEqual(expected);
});
});
// Test the combined desugarVersion and pythonVersionToSemantic functions
describe('pythonVersions', () => {
it.each([
['3.13', {version: '3.13', freethreaded: false}],
['3.13t', {version: '3.13', freethreaded: true}],
['3.13.1', {version: '3.13.1', freethreaded: false}],
['3.13.1t', {version: '3.13.1', freethreaded: true}],
['3.14-dev', {version: '~3.14.0-0', freethreaded: false}],
['3.14t-dev', {version: '~3.14.0-0', freethreaded: true}]
])('%s -> %s', (input, expected) => {
const {version, freethreaded} = desugarVersion(input);
const semanticVersionSpec = pythonVersionToSemantic(version, false);
expect({version: semanticVersionSpec, freethreaded}).toEqual(expected);
});
it.each([
['3.13', {version: '~3.13.0-0', freethreaded: false}],
['3.13t', {version: '~3.13.0-0', freethreaded: true}],
['3.13.1', {version: '3.13.1', freethreaded: false}],
['3.13.1t', {version: '3.13.1', freethreaded: true}],
['3.14-dev', {version: '~3.14.0-0', freethreaded: false}],
['3.14t-dev', {version: '~3.14.0-0', freethreaded: true}]
])('%s (allowPreReleases=true) -> %s', (input, expected) => {
const {version, freethreaded} = desugarVersion(input);
const semanticVersionSpec = pythonVersionToSemantic(version, true);
expect({version: semanticVersionSpec, freethreaded}).toEqual(expected);
});
});

View File

@ -24,7 +24,7 @@ import * as core from '@actions/core';
import * as finder from '../src/find-python'; import * as finder from '../src/find-python';
import * as installer from '../src/install-python'; import * as installer from '../src/install-python';
import manifestData from './data/versions-manifest.json'; const manifestData = require('./data/versions-manifest.json');
describe('Finder tests', () => { describe('Finder tests', () => {
let writeSpy: jest.SpyInstance; let writeSpy: jest.SpyInstance;
@ -56,7 +56,7 @@ describe('Finder tests', () => {
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await finder.useCpythonVersion('3.x', 'x64', true, false, false, false); await finder.useCpythonVersion('3.x', 'x64', true, false);
expect(spyCoreAddPath).toHaveBeenCalled(); expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith( expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation', 'pythonLocation',
@ -73,7 +73,7 @@ describe('Finder tests', () => {
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await finder.useCpythonVersion('3.x', 'x64', false, false, false, false); await finder.useCpythonVersion('3.x', 'x64', false, false);
expect(spyCoreAddPath).not.toHaveBeenCalled(); expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled(); expect(spyCoreExportVariable).not.toHaveBeenCalled();
}); });
@ -95,12 +95,7 @@ describe('Finder tests', () => {
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
}); });
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await expect( await finder.useCpythonVersion('1.2.3', 'x64', true, false);
finder.useCpythonVersion('1.2.3', 'x64', true, false, false, false)
).resolves.toEqual({
impl: 'CPython',
version: '1.2.3'
});
expect(spyCoreAddPath).toHaveBeenCalled(); expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith( expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation', 'pythonLocation',
@ -127,26 +122,14 @@ describe('Finder tests', () => {
const pythonDir: string = path.join( const pythonDir: string = path.join(
toolDir, toolDir,
'Python', 'Python',
'1.2.4-beta.2', '1.2.3-beta.2',
'x64' 'x64'
); );
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
}); });
// This will throw if it doesn't find it in the manifest (because no such version exists) // This will throw if it doesn't find it in the manifest (because no such version exists)
await expect( await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, false);
finder.useCpythonVersion(
'1.2.4-beta.2',
'x64',
false,
false,
false,
false
)
).resolves.toEqual({
impl: 'CPython',
version: '1.2.4-beta.2'
});
}); });
it('Check-latest true, finds the latest version in the manifest', async () => { it('Check-latest true, finds the latest version in the manifest', async () => {
@ -193,25 +176,18 @@ describe('Finder tests', () => {
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await finder.useCpythonVersion('1.2', 'x64', true, true, false, false); await finder.useCpythonVersion('1.2', 'x64', true, true);
expect(infoSpy).toHaveBeenCalledWith("Resolved as '1.2.3'"); expect(infoSpy).toHaveBeenCalledWith("Resolved as '1.2.3'");
expect(infoSpy).toHaveBeenCalledWith( expect(infoSpy).toHaveBeenCalledWith(
'Version 1.2.3 was not found in the local cache' 'Version 1.2.3 was not found in the local cache'
); );
expect(infoSpy).toHaveBeenCalledWith( expect(infoSpy).toBeCalledWith(
'Version 1.2.3 is available for downloading' 'Version 1.2.3 is available for downloading'
); );
expect(installSpy).toHaveBeenCalled(); expect(installSpy).toHaveBeenCalled();
expect(addPathSpy).toHaveBeenCalledWith(expPath); expect(addPathSpy).toHaveBeenCalledWith(expPath);
await finder.useCpythonVersion( await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, true);
'1.2.4-beta.2',
'x64',
false,
true,
false,
false
);
expect(spyCoreAddPath).toHaveBeenCalled(); expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith( expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation', 'pythonLocation',
@ -223,74 +199,11 @@ describe('Finder tests', () => {
); );
}); });
it('Finds stable Python version if it is not installed, but exists in the manifest, skipping newer pre-release', async () => {
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => {
const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', 'x64');
await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
});
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await expect(
finder.useCpythonVersion('1.2', 'x64', false, false, false, false)
).resolves.toEqual({
impl: 'CPython',
version: '1.2.3'
});
});
it('Finds Python version if it is not installed, but exists in the manifest, pre-release fallback', async () => {
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => {
const pythonDir: string = path.join(
toolDir,
'Python',
'1.1.0-beta.2',
'x64'
);
await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
});
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await expect(
finder.useCpythonVersion('1.1', 'x64', false, false, false, false)
).rejects.toThrow();
await expect(
finder.useCpythonVersion('1.1', 'x64', false, false, true, false)
).resolves.toEqual({
impl: 'CPython',
version: '1.1.0-beta.2'
});
// Check 1.1.0 version specifier does not fallback to '1.1.0-beta.2'
await expect(
finder.useCpythonVersion('1.1.0', 'x64', false, false, true, false)
).rejects.toThrow();
});
it('Errors if Python is not installed', async () => { it('Errors if Python is not installed', async () => {
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
let thrown = false; let thrown = false;
try { try {
await finder.useCpythonVersion( await finder.useCpythonVersion('3.300000', 'x64', true, false);
'3.300000',
'x64',
true,
false,
false,
false
);
} catch { } catch {
thrown = true; thrown = true;
} }

View File

@ -1,256 +0,0 @@
import fs from 'fs';
import {HttpClient} from '@actions/http-client';
import * as ifm from '@actions/http-client/lib/interfaces';
import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec';
import * as core from '@actions/core';
import * as path from 'path';
import * as installer from '../src/install-graalpy';
import {
IGraalPyManifestRelease,
IGraalPyManifestAsset,
IS_WINDOWS
} from '../src/utils';
import manifestData from './data/graalpy.json';
const architecture = 'x64';
const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp');
/* GraalPy doesn't have a windows release yet */
const describeSkipOnWindows = IS_WINDOWS ? describe.skip : describe;
describe('graalpyVersionToSemantic', () => {
it.each([
['23.0.0a1', '23.0.0a1'],
['23.0.0', '23.0.0'],
['23.0.x', '23.0.x'],
['23.x', '23.x']
])('%s -> %s', (input, expected) => {
expect(installer.graalPyTagToVersion(input)).toEqual(expected);
});
});
describeSkipOnWindows('findRelease', () => {
const result = JSON.stringify(manifestData);
const releases = JSON.parse(result) as IGraalPyManifestRelease[];
const extension = 'tar.gz';
const arch = installer.toGraalPyArchitecture(architecture);
const platform = installer.toGraalPyPlatform(process.platform);
const extensionName = `${platform}-${arch}.${extension}`;
const files: IGraalPyManifestAsset = {
name: `graalpython-23.0.0-${extensionName}`,
browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.0.0/graalpython-23.0.0-${extensionName}`
};
const filesRC1: IGraalPyManifestAsset = {
name: `graalpython-23.1.0a1-${extensionName}`,
browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.1.0a1/graalpython-23.1.0a1-${extensionName}`
};
let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
beforeEach(() => {
infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {});
warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null);
debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null);
});
it("GraalPy version doesn't match", () => {
const graalpyVersion = '12.0.0';
expect(
installer.findRelease(releases, graalpyVersion, architecture, false)
).toEqual(null);
});
it('GraalPy version matches', () => {
const graalpyVersion = '23.0.0';
expect(
installer.findRelease(releases, graalpyVersion, architecture, false)
).toMatchObject({
foundAsset: files,
resolvedGraalPyVersion: graalpyVersion
});
});
it('Preview version of GraalPy is found', () => {
const graalpyVersion = installer.graalPyTagToVersion('vm-23.1.0a1');
expect(
installer.findRelease(releases, graalpyVersion, architecture, false)
).toMatchObject({
foundAsset: {
name: `graalpython-23.1.0a1-${extensionName}`,
browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.1.0a1/graalpython-23.1.0a1-${extensionName}`
},
resolvedGraalPyVersion: '23.1.0-a.1'
});
});
it('Latest GraalPy is found', () => {
const graalpyVersion = 'x';
expect(
installer.findRelease(releases, graalpyVersion, architecture, false)
).toMatchObject({
foundAsset: files,
resolvedGraalPyVersion: '23.0.0'
});
});
it('GraalPy version matches semver (pre-release)', () => {
const graalpyVersion = '23.1.x';
expect(
installer.findRelease(releases, graalpyVersion, architecture, false)
).toBeNull();
expect(
installer.findRelease(releases, graalpyVersion, architecture, true)
).toMatchObject({
foundAsset: filesRC1,
resolvedGraalPyVersion: '23.1.0-a.1'
});
});
});
describeSkipOnWindows('installGraalPy', () => {
let tcFind: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
let spyExtractZip: jest.SpyInstance;
let spyExtractTar: jest.SpyInstance;
let spyFsReadDir: jest.SpyInstance;
let spyFsWriteFile: jest.SpyInstance;
let spyHttpClient: jest.SpyInstance;
let spyExistsSync: jest.SpyInstance;
let spyExec: jest.SpyInstance;
let spySymlinkSync: jest.SpyInstance;
let spyDownloadTool: jest.SpyInstance;
let spyCacheDir: jest.SpyInstance;
let spyChmodSync: jest.SpyInstance;
beforeEach(() => {
tcFind = jest.spyOn(tc, 'find');
tcFind.mockImplementation(() =>
path.join('GraalPy', '3.6.12', architecture)
);
spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'GraalPy'));
spyExtractZip = jest.spyOn(tc, 'extractZip');
spyExtractZip.mockImplementation(() => tempDir);
spyExtractTar = jest.spyOn(tc, 'extractTar');
spyExtractTar.mockImplementation(() => tempDir);
infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {});
warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null);
debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null);
spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation(() => ['GraalPyTest']);
spyFsWriteFile = jest.spyOn(fs, 'writeFileSync');
spyFsWriteFile.mockImplementation(() => undefined);
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation(
async (): Promise<ifm.TypedResponse<IGraalPyManifestRelease[]>> => {
const result = JSON.stringify(manifestData);
return {
statusCode: 200,
headers: {},
result: JSON.parse(result) as IGraalPyManifestRelease[]
};
}
);
spyExec = jest.spyOn(exec, 'exec');
spyExec.mockImplementation(() => undefined);
spySymlinkSync = jest.spyOn(fs, 'symlinkSync');
spySymlinkSync.mockImplementation(() => undefined);
spyExistsSync = jest.spyOn(fs, 'existsSync');
spyExistsSync.mockImplementation(() => false);
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it('throw if release is not found', async () => {
await expect(
installer.installGraalPy('7.3.3', architecture, false, undefined)
).rejects.toThrow(
`GraalPy version 7.3.3 with arch ${architecture} not found`
);
expect(spyHttpClient).toHaveBeenCalled();
expect(spyDownloadTool).not.toHaveBeenCalled();
expect(spyExec).not.toHaveBeenCalled();
});
it('found and install GraalPy', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '21.3.0', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
installer.installGraalPy('21.x', architecture, false, undefined)
).resolves.toEqual({
installDir: path.join(toolDir, 'GraalPy', '21.3.0', architecture),
resolvedGraalPyVersion: '21.3.0'
});
expect(spyHttpClient).toHaveBeenCalled();
expect(spyDownloadTool).toHaveBeenCalled();
expect(spyCacheDir).toHaveBeenCalled();
expect(spyExec).toHaveBeenCalled();
});
it('found and install GraalPy, pre-release fallback', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.1.0', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
installer.installGraalPy('23.1.x', architecture, false, undefined)
).rejects.toThrow();
await expect(
installer.installGraalPy('23.1.x', architecture, true, undefined)
).resolves.toEqual({
installDir: path.join(toolDir, 'GraalPy', '23.1.0', architecture),
resolvedGraalPyVersion: '23.1.0-a.1'
});
expect(spyHttpClient).toHaveBeenCalled();
expect(spyDownloadTool).toHaveBeenCalled();
expect(spyCacheDir).toHaveBeenCalled();
expect(spyExec).toHaveBeenCalled();
});
});

View File

@ -1,7 +1,7 @@
import fs from 'fs'; import fs from 'fs';
import {HttpClient} from '@actions/http-client'; import {HttpClient} from '@actions/http-client';
import * as ifm from '@actions/http-client/lib/interfaces'; import * as ifm from '@actions/http-client/interfaces';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import * as core from '@actions/core'; import * as core from '@actions/core';
@ -14,7 +14,7 @@ import {
IS_WINDOWS IS_WINDOWS
} from '../src/utils'; } from '../src/utils';
import manifestData from './data/pypy.json'; const manifestData = require('./data/pypy.json');
let architecture: string; let architecture: string;
if (IS_WINDOWS) { if (IS_WINDOWS) {
@ -51,12 +51,6 @@ describe('findRelease', () => {
platform: process.platform, platform: process.platform,
download_url: `https://test.download.python.org/pypy/pypy3.6-v7.3.3-${extensionName}` download_url: `https://test.download.python.org/pypy/pypy3.6-v7.3.3-${extensionName}`
}; };
const filesRC1: IPyPyManifestAsset = {
filename: `pypy3.6-v7.4.0rc1-${extensionName}`,
arch: architecture,
platform: process.platform,
download_url: `https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-${extensionName}`
};
let getBooleanInputSpy: jest.SpyInstance; let getBooleanInputSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance; let warningSpy: jest.SpyInstance;
@ -78,13 +72,7 @@ describe('findRelease', () => {
const pythonVersion = '3.6'; const pythonVersion = '3.6';
const pypyVersion = '7.3.7'; const pypyVersion = '7.3.7';
expect( expect(
installer.findRelease( installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual(null); ).toEqual(null);
}); });
@ -92,13 +80,7 @@ describe('findRelease', () => {
const pythonVersion = '3.6'; const pythonVersion = '3.6';
const pypyVersion = '7.3.3'; const pypyVersion = '7.3.3';
expect( expect(
installer.findRelease( installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({ ).toEqual({
foundAsset: files, foundAsset: files,
resolvedPythonVersion: '3.6.12', resolvedPythonVersion: '3.6.12',
@ -110,13 +92,7 @@ describe('findRelease', () => {
const pythonVersion = '3.6'; const pythonVersion = '3.6';
const pypyVersion = '7.x'; const pypyVersion = '7.x';
expect( expect(
installer.findRelease( installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({ ).toEqual({
foundAsset: files, foundAsset: files,
resolvedPythonVersion: '3.6.12', resolvedPythonVersion: '3.6.12',
@ -128,13 +104,7 @@ describe('findRelease', () => {
const pythonVersion = '3.7'; const pythonVersion = '3.7';
const pypyVersion = installer.pypyVersionToSemantic('7.3.3rc2'); const pypyVersion = installer.pypyVersionToSemantic('7.3.3rc2');
expect( expect(
installer.findRelease( installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({ ).toEqual({
foundAsset: { foundAsset: {
filename: `test${extension}`, filename: `test${extension}`,
@ -151,13 +121,7 @@ describe('findRelease', () => {
const pythonVersion = '3.6'; const pythonVersion = '3.6';
const pypyVersion = 'x'; const pypyVersion = 'x';
expect( expect(
installer.findRelease( installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({ ).toEqual({
foundAsset: files, foundAsset: files,
resolvedPythonVersion: '3.6.12', resolvedPythonVersion: '3.6.12',
@ -165,45 +129,12 @@ describe('findRelease', () => {
}); });
}); });
it('Python version and PyPy version matches semver (pre-release)', () => {
const pythonVersion = '3.6';
const pypyVersion = '7.4.x';
expect(
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toBeNull();
expect(
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
true
)
).toEqual({
foundAsset: filesRC1,
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.4.0rc1'
});
});
it('Nightly release is found', () => { it('Nightly release is found', () => {
const pythonVersion = '3.6'; const pythonVersion = '3.6';
const pypyVersion = 'nightly'; const pypyVersion = 'nightly';
const filename = IS_WINDOWS ? 'filename.zip' : 'filename.tar.bz2'; const filename = IS_WINDOWS ? 'filename.zip' : 'filename.tar.bz2';
expect( expect(
installer.findRelease( installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({ ).toEqual({
foundAsset: { foundAsset: {
filename: filename, filename: filename,
@ -265,7 +196,7 @@ describe('installPyPy', () => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation( spyHttpClient.mockImplementation(
async (): Promise<ifm.TypedResponse<IPyPyManifestRelease[]>> => { async (): Promise<ifm.ITypedResponse<IPyPyManifestRelease[]>> => {
const result = JSON.stringify(manifestData); const result = JSON.stringify(manifestData);
return { return {
statusCode: 200, statusCode: 200,
@ -293,8 +224,8 @@ describe('installPyPy', () => {
it('throw if release is not found', async () => { it('throw if release is not found', async () => {
await expect( await expect(
installer.installPyPy('7.3.3', '3.6.17', architecture, false, undefined) installer.installPyPy('7.3.3', '3.6.17', architecture, undefined)
).rejects.toThrow( ).rejects.toThrowError(
`PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found` `PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found`
); );
@ -313,7 +244,7 @@ describe('installPyPy', () => {
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
installer.installPyPy('7.x', '3.6.12', architecture, false, undefined) installer.installPyPy('7.3.x', '3.6.12', architecture, undefined)
).resolves.toEqual({ ).resolves.toEqual({
installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture), installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture),
resolvedPythonVersion: '3.6.12', resolvedPythonVersion: '3.6.12',
@ -326,31 +257,4 @@ describe('installPyPy', () => {
expect(spyCacheDir).toHaveBeenCalled(); expect(spyCacheDir).toHaveBeenCalled();
expect(spyExec).toHaveBeenCalled(); expect(spyExec).toHaveBeenCalled();
}); });
it('found and install PyPy, pre-release fallback', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.6.12', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
installer.installPyPy('7.4.x', '3.6.12', architecture, false, undefined)
).rejects.toThrow();
await expect(
installer.installPyPy('7.4.x', '3.6.12', architecture, true, undefined)
).resolves.toEqual({
installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture),
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.4.0rc1'
});
expect(spyHttpClient).toHaveBeenCalled();
expect(spyDownloadTool).toHaveBeenCalled();
expect(spyExistsSync).toHaveBeenCalled();
expect(spyCacheDir).toHaveBeenCalled();
expect(spyExec).toHaveBeenCalled();
});
}); });

View File

@ -1,77 +0,0 @@
import {
getManifest,
getManifestFromRepo,
getManifestFromURL
} from '../src/install-python';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache';
jest.mock('@actions/http-client');
jest.mock('@actions/tool-cache');
jest.mock('@actions/tool-cache', () => ({
getManifestFromRepo: jest.fn()
}));
const mockManifest = [
{
version: '1.0.0',
stable: true,
files: [
{
filename: 'tool-v1.0.0-linux-x64.tar.gz',
platform: 'linux',
arch: 'x64',
download_url: 'https://example.com/tool-v1.0.0-linux-x64.tar.gz'
}
]
}
];
describe('getManifest', () => {
beforeEach(() => {
jest.resetAllMocks();
});
it('should return manifest from repo', async () => {
(tc.getManifestFromRepo as jest.Mock).mockResolvedValue(mockManifest);
const manifest = await getManifest();
expect(manifest).toEqual(mockManifest);
});
it('should return manifest from URL if repo fetch fails', async () => {
(tc.getManifestFromRepo as jest.Mock).mockRejectedValue(
new Error('Fetch failed')
);
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: mockManifest
});
const manifest = await getManifest();
expect(manifest).toEqual(mockManifest);
});
});
describe('getManifestFromRepo', () => {
it('should return manifest from repo', async () => {
(tc.getManifestFromRepo as jest.Mock).mockResolvedValue(mockManifest);
const manifest = await getManifestFromRepo();
expect(manifest).toEqual(mockManifest);
});
});
describe('getManifestFromURL', () => {
it('should return manifest from URL', async () => {
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: mockManifest
});
const manifest = await getManifestFromURL();
expect(manifest).toEqual(mockManifest);
});
it('should throw error if unable to get manifest from URL', async () => {
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: null
});
await expect(getManifestFromURL()).rejects.toThrow(
'Unable to get manifest from'
);
});
});

View File

@ -1,7 +0,0 @@
import numpy as np
a = np.array([2, 3, 4])
print(type(a))
b = np.array([1.2, 3.5, 5.1])
print(type(b))

View File

@ -1,22 +1,9 @@
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 io from '@actions/io';
import fs from 'fs';
import path from 'path';
import { import {
validateVersion, validateVersion,
validatePythonVersionFormatForPyPy, validatePythonVersionFormatForPyPy,
isCacheFeatureAvailable, isCacheFeatureAvailable
getVersionInputFromFile,
getVersionInputFromPlainFile,
getVersionInputFromTomlFile,
getNextPageUrl,
isGhes,
IS_WINDOWS,
getDownloadFileName,
getVersionInputFromToolVersions
} from '../src/utils'; } from '../src/utils';
jest.mock('@actions/cache'); jest.mock('@actions/cache');
@ -86,228 +73,3 @@ describe('isCacheFeatureAvailable', () => {
expect(isCacheFeatureAvailable()).toBe(true); expect(isCacheFeatureAvailable()).toBe(true);
}); });
}); });
const tempDir = path.join(
__dirname,
'runner',
path.join(Math.random().toString(36).substring(7)),
'temp'
);
describe('Version from file test', () => {
it.each([getVersionInputFromPlainFile, getVersionInputFromFile])(
'Version from plain file test',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'python-version.file';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
const pythonVersionFileContent = '3.7';
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersionFileContent]);
}
);
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
'Version from standard pyproject.toml test',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'pyproject.toml';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
const pythonVersion = '>=3.7.0';
const pythonVersionFileContent = `[project]\nrequires-python = "${pythonVersion}"`;
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
}
);
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
'Version from poetry pyproject.toml test',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'pyproject.toml';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
const pythonVersion = '>=3.7.0';
const pythonVersionFileContent = `[tool.poetry.dependencies]\npython = "${pythonVersion}"`;
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
}
);
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
'Version undefined',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'pyproject.toml';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
fs.writeFileSync(pythonVersionFilePath, ``);
expect(_fn(pythonVersionFilePath)).toEqual([]);
}
);
it.each([getVersionInputFromToolVersions])(
'Version from .tool-versions',
async _fn => {
const toolVersionFileName = '.tool-versions';
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
const toolVersionContent = 'python 3.9.10\nnodejs 16';
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
expect(_fn(toolVersionFilePath)).toEqual(['3.9.10']);
}
);
it.each([getVersionInputFromToolVersions])(
'Version from .tool-versions with comment',
async _fn => {
const toolVersionFileName = '.tool-versions';
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
const toolVersionContent = '# python 3.8\npython 3.9';
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
expect(_fn(toolVersionFilePath)).toEqual(['3.9']);
}
);
it.each([getVersionInputFromToolVersions])(
'Version from .tool-versions with whitespace',
async _fn => {
const toolVersionFileName = '.tool-versions';
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
const toolVersionContent = ' python 3.10 ';
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
expect(_fn(toolVersionFilePath)).toEqual(['3.10']);
}
);
it.each([getVersionInputFromToolVersions])(
'Version from .tool-versions with v prefix',
async _fn => {
const toolVersionFileName = '.tool-versions';
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
const toolVersionContent = 'python v3.9.10';
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
expect(_fn(toolVersionFilePath)).toEqual(['3.9.10']);
}
);
it.each([getVersionInputFromToolVersions])(
'Version from .tool-versions with pypy version',
async _fn => {
const toolVersionFileName = '.tool-versions';
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
const toolVersionContent = 'python pypy3.10-7.3.14';
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
expect(_fn(toolVersionFilePath)).toEqual(['pypy3.10-7.3.14']);
}
);
it.each([getVersionInputFromToolVersions])(
'Version from .tool-versions with alpha Releases',
async _fn => {
const toolVersionFileName = '.tool-versions';
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
const toolVersionContent = 'python 3.14.0a5t';
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
expect(_fn(toolVersionFilePath)).toEqual(['3.14.0a5t']);
}
);
it.each([getVersionInputFromToolVersions])(
'Version from .tool-versions with dev suffix',
async _fn => {
const toolVersionFileName = '.tool-versions';
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
const toolVersionContent = 'python 3.14t-dev';
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
expect(_fn(toolVersionFilePath)).toEqual(['3.14t-dev']);
}
);
});
describe('getNextPageUrl', () => {
it('GitHub API pagination next page is parsed correctly', () => {
function generateResponse(link: string) {
return {
statusCode: 200,
result: null,
headers: {
link: link
}
};
}
const page1Links =
'<https://api.github.com/repositories/129883600/releases?page=2>; rel="next", <https://api.github.com/repositories/129883600/releases?page=3>; rel="last"';
expect(getNextPageUrl(generateResponse(page1Links))).toStrictEqual(
'https://api.github.com/repositories/129883600/releases?page=2'
);
const page2Links =
'<https://api.github.com/repositories/129883600/releases?page=1>; rel="prev", <https://api.github.com/repositories/129883600/releases?page=1>; rel="first"';
expect(getNextPageUrl(generateResponse(page2Links))).toBeNull();
});
});
describe('getDownloadFileName', () => {
const originalEnv = process.env;
const tempDir = path.join(__dirname, 'runner', 'temp');
beforeEach(() => {
process.env = {...originalEnv};
});
afterEach(() => {
process.env = originalEnv;
});
it('should return the correct path on Windows', () => {
if (IS_WINDOWS) {
process.env['RUNNER_TEMP'] = tempDir;
const downloadUrl =
'https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-win32-x64.zip';
const expectedPath = path.join(
process.env.RUNNER_TEMP,
path.basename(downloadUrl)
);
expect(getDownloadFileName(downloadUrl)).toBe(expectedPath);
}
});
it('should return undefined on non-Windows', () => {
if (!IS_WINDOWS) {
const downloadUrl =
'https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-linux-x64.tar.gz';
expect(getDownloadFileName(downloadUrl)).toBeUndefined();
}
});
});
describe('isGhes', () => {
const pristineEnv = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {...pristineEnv};
});
afterAll(() => {
process.env = pristineEnv;
});
it('returns false when the GITHUB_SERVER_URL environment variable is not defined', async () => {
delete process.env['GITHUB_SERVER_URL'];
expect(isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable is set to github.com', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://github.com';
expect(isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable is set to a GitHub Enterprise Cloud-style URL', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://contoso.ghe.com';
expect(isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable has a .localhost suffix', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://mock-github.localhost';
expect(isGhes()).toBeFalsy();
});
it('returns true when the GITHUB_SERVER_URL environment variable is set to some other URL', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://src.onpremise.fabrikam.com';
expect(isGhes()).toBeTruthy();
});
});

View File

@ -1,3 +0,0 @@
import sys
if __name__ == '__main__':
print(f"Using GIL: {sys._is_gil_enabled()}\n")

View File

@ -11,7 +11,7 @@ inputs:
description: "Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv, poetry." description: "Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv, poetry."
required: false required: false
architecture: architecture:
description: "The target architecture (x86, x64, arm64) of the Python or PyPy interpreter." description: "The target architecture (x86, x64) of the Python or PyPy interpreter."
check-latest: check-latest:
description: "Set this option if you want the action to check for the latest available version that satisfies the version spec." description: "Set this option if you want the action to check for the latest available version that satisfies the version spec."
default: false default: false
@ -23,12 +23,6 @@ inputs:
update-environment: update-environment:
description: "Set this option if you want the action to update environment variables." description: "Set this option if you want the action to update environment variables."
default: true default: true
allow-prereleases:
description: "When 'true', a version range passed to 'python-version' input will match prerelease versions if no GA versions are found. Only 'x.y' version range is supported for CPython."
default: false
freethreaded:
description: "When 'true', use the freethreaded version of Python."
default: false
outputs: outputs:
python-version: python-version:
description: "The installed Python or PyPy version. Useful when given a version range as input." description: "The installed Python or PyPy version. Useful when given a version range as input."
@ -37,7 +31,7 @@ outputs:
python-path: python-path:
description: "The absolute path to the Python or PyPy executable." description: "The absolute path to the Python or PyPy executable."
runs: runs:
using: 'node20' using: 'node16'
main: 'dist/setup/index.js' main: 'dist/setup/index.js'
post: 'dist/cache-save/index.js' post: 'dist/cache-save/index.js'
post-if: success() post-if: success()

52716
dist/cache-save/index.js vendored

File diff suppressed because one or more lines are too long

61320
dist/setup/index.js vendored

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@ Integration of caching functionality into `actions/setup-python` action will bri
We will add support for Pip and Pipenv dependency caching. We will add support for Pip and Pipenv dependency caching.
We won't pursue the goal to provide wide customization of caching in the scope of `actions/setup-python` action. The purpose of this integration is to cover ~90% of basic use-cases. The action does not support dependency-specific caching for each job. If different dependencies are installed across jobs the cache from the first job will be used in the second job. To manage this aspect, users should create separate caches for jobs with different requirements. If users need flexible customization, we will advise them to use `actions/cache` directly. We won't pursue the goal to provide wide customization of caching in the scope of `actions/setup-python` action. The purpose of this integration is to cover ~90% of basic use-cases. If users need flexible customization, we will advise them to use `actions/cache` directly.
## Decision ## Decision

View File

@ -2,7 +2,7 @@
- [Using the python-version input](advanced-usage.md#using-the-python-version-input) - [Using the python-version input](advanced-usage.md#using-the-python-version-input)
- [Specifying a Python version](advanced-usage.md#specifying-a-python-version) - [Specifying a Python version](advanced-usage.md#specifying-a-python-version)
- [Specifying a PyPy version](advanced-usage.md#specifying-a-pypy-version) - [Specifying a PyPy version](advanced-usage.md#specifying-a-pypy-version)
- [Specifying multiple Python/PyPy versions](advanced-usage.md#specifying-multiple-pythonpypy-versions) - [Specifying multiple Python and PyPy versions](advanced-usage.md#specifying-multiple-python/pypy-version)
- [Matrix Testing](advanced-usage.md#matrix-testing) - [Matrix Testing](advanced-usage.md#matrix-testing)
- [Using the python-version-file input](advanced-usage.md#using-the-python-version-file-input) - [Using the python-version-file input](advanced-usage.md#using-the-python-version-file-input)
- [Check latest version](advanced-usage.md#check-latest-version) - [Check latest version](advanced-usage.md#check-latest-version)
@ -11,30 +11,28 @@
- [Outputs](advanced-usage.md#outputs) - [Outputs](advanced-usage.md#outputs)
- [Environment variables](advanced-usage.md#environment-variables) - [Environment variables](advanced-usage.md#environment-variables)
- [Using update-environment flag](advanced-usage.md#using-update-environment-flag) - [Using update-environment flag](advanced-usage.md#using-update-environment-flag)
- [Available versions of Python and PyPy](advanced-usage.md#available-versions-of-python-pypy-and-graalpy) - [Available versions of Python and PyPy](advanced-usage.md#available-versions-of-python-and-pypy)
- [Python](advanced-usage.md#python) - [Python](advanced-usage.md#python)
- [PyPy](advanced-usage.md#pypy) - [PyPy](advanced-usage.md#pypy)
- [GraalPy](advanced-usage.md#graalpy)
- [Hosted tool cache](advanced-usage.md#hosted-tool-cache) - [Hosted tool cache](advanced-usage.md#hosted-tool-cache)
- [Using `setup-python` with a self-hosted runner](advanced-usage.md#using-setup-python-with-a-self-hosted-runner) - [Using `setup-python` with a self-hosted runner](advanced-usage.md#using-setup-python-with-a-self-hosted-runner)
- [Windows](advanced-usage.md#windows) - [Windows](advanced-usage.md#windows)
- [Linux](advanced-usage.md#linux) - [Linux](advanced-usage.md#linux)
- [macOS](advanced-usage.md#macos) - [macOS](advanced-usage.md#macos)
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes) - [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
- [Allow pre-releases](advanced-usage.md#allow-pre-releases)
## Using the `python-version` input ## Using the `python-version` input
### Specifying a Python version ### Specifying a Python version
If there is a specific version of Python that you need and you don't want to worry about any potential breaking changes due to patch updates (going from `3.12.6` to `3.12.7` for example), you should specify the **exact major, minor, and patch version** (such as `3.12.6`): If there is a specific version of Python that you need and you don't want to worry about any potential breaking changes due to patch updates (going from `3.7.5` to `3.7.6` for example), you should specify the **exact major, minor, and patch version** (such as `3.7.5`):
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.12.6' python-version: '3.7.5'
- run: python my_script.py - run: python my_script.py
``` ```
@ -45,10 +43,10 @@ You can specify **only a major and minor version** if you are okay with the most
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.7'
- run: python my_script.py - run: python my_script.py
``` ```
- There will be a single patch version already installed on each runner for every minor version of Python that is supported. - There will be a single patch version already installed on each runner for every minor version of Python that is supported.
@ -59,10 +57,10 @@ You can specify the version with **prerelease tag** to download and set up an ac
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.14.0-alpha.1' python-version: '3.11.0-alpha.1'
- run: python my_script.py - run: python my_script.py
``` ```
@ -70,68 +68,32 @@ It's also possible to use **x.y-dev syntax** to download and set up the latest p
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.14-dev' python-version: '3.11-dev'
- run: python my_script.py
```
You can specify the [free threading](https://docs.python.org/3/howto/free-threading-python.html) version of Python by setting the `freethreaded` input to `true` or by using the special **t** suffix in some cases.
You can use the **t** suffix when specifying the major and minor version (e.g., `3.13t`), with a patch version (e.g., `3.13.1t`), or with the **x.y-dev syntax** (e.g., `3.14t-dev`).
Free threaded Python is only available starting with the 3.13 release.
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13t'
- run: python my_script.py
```
Note that the **t** suffix is not `semver` syntax. If you wish to specify a range, you must use the `freethreaded` input instead of the `t` suffix.
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '>=3.13'
freethreaded: true
- run: python my_script.py - run: python my_script.py
``` ```
You can also use several types of ranges that are specified in [semver](https://github.com/npm/node-semver#ranges), for instance: You can also use several types of ranges that are specified in [semver](https://github.com/npm/node-semver#ranges), for instance:
- **[ranges](https://github.com/npm/node-semver#ranges)** to download and set up the latest available version of Python satisfying a range:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '>=3.9 <3.14'
- run: python my_script.py
```
- **[hyphen ranges](https://github.com/npm/node-semver#hyphen-ranges-xyz---abc)** to download and set up the latest available version of Python (includes both pre-release and stable versions): - **[hyphen ranges](https://github.com/npm/node-semver#hyphen-ranges-xyz---abc)** to download and set up the latest available version of Python (includes both pre-release and stable versions):
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13.0-alpha - 3.13.0' python-version: '3.11.0-alpha - 3.11.0'
- run: python my_script.py - run: python my_script.py
``` ```
- **[x-ranges](https://github.com/npm/node-semver#x-ranges-12x-1x-12-)** to specify the latest stable version of Python (for the specified major version): - **[x-ranges](https://github.com/npm/node-semver#x-ranges-12x-1x-12-)** to specify the latest stable version of Python (for specified major version):
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.x' python-version: '3.x'
- run: python my_script.py - run: python my_script.py
@ -143,8 +105,8 @@ The version of PyPy should be specified in the format `pypy<python_version>[-v<p
The `-v<pypy_version>` parameter is optional and can be skipped. The latest PyPy version will be used in this case. The `-v<pypy_version>` parameter is optional and can be skipped. The latest PyPy version will be used in this case.
``` ```
pypy3.10 or pypy-3.10 # the latest available version of PyPy that supports Python 3.10 pypy3.8 or pypy-3.8 # the latest available version of PyPy that supports Python 3.8
pypy3.9 or pypy-3.9 # the latest available version of PyPy that supports Python 3.9 pypy2.7 or pypy-2.7 # the latest available version of PyPy that supports Python 2.7
pypy3.7-v7.3.3 or pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3 pypy3.7-v7.3.3 or pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3
pypy3.7-v7.x or pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x pypy3.7-v7.x or pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x
pypy3.7-v7.3.3rc1 or pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy pypy3.7-v7.3.3rc1 or pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy
@ -160,18 +122,18 @@ jobs:
strategy: strategy:
matrix: matrix:
python-version: python-version:
- 'pypy3.10' # the latest available version of PyPy that supports Python 3.10 - 'pypy3.7' # the latest available version of PyPy that supports Python 3.7
- 'pypy3.10-v7.3.17' # Python 3.10 and PyPy 7.3.17 - 'pypy3.7-v7.3.3' # Python 3.7 and PyPy 7.3.3
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- run: python my_script.py - run: python my_script.py
``` ```
More details on the syntax for PyPy can be found in the [Available versions of PyPy](#pypy) section. More details on PyPy syntax can be found in the [Available versions of PyPy](#pypy) section.
### Specifying multiple Python/PyPy versions ### Specifying multiple Python/PyPy version
The python-version input can get multiple python/pypy versions. The last specified version will be used as a default one. The python-version input can get multiple python/pypy versions. The last specified version will be used as a default one.
Download and set up multiple Python versions: Download and set up multiple Python versions:
@ -181,13 +143,13 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: | python-version: |
3.11 3.8
3.12 3.9
3.13 3.10
- run: python my_script.py - run: python my_script.py
``` ```
@ -198,13 +160,13 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: | python-version: |
pypy-3.10-v7.3.x pypy-3.7-v7.3.x
pypy3.10-nightly pypy3.9-nightly
pypy3.9 pypy3.8
- run: python my_script.py - run: python my_script.py
``` ```
@ -215,21 +177,21 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: | python-version: |
3.11 3.8
3.12 3.9
pypy3.10-nightly pypy3.9-nightly
pypy3.10 pypy3.8
3.13 3.10
- run: python my_script.py - run: python my_script.py
``` ```
### Matrix Testing ### Matrix Testing
Using `setup-python` it's possible to use the [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of Python or PyPy: Using `setup-python` it's possible to use [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of Python or PyPy:
```yaml ```yaml
jobs: jobs:
@ -237,12 +199,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
python-version: ['3.x', 'pypy3.8', 'pypy3.9' ] python-version: [ '2.x', '3.x', 'pypy2.7', 'pypy3.7', 'pypy3.8' ]
name: Python ${{ matrix.python-version }} sample name: Python ${{ matrix.python-version }} sample
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
architecture: x64 architecture: x64
@ -256,23 +218,21 @@ jobs:
build: build:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.9', '3.10', '3.11', 'pypy3.9'] python-version: ['2.7', '3.7', '3.8', '3.9', '3.10', 'pypy2.7', 'pypy3.8']
exclude: exclude:
- os: macos-latest - os: macos-latest
python-version: '3.9' python-version: '3.8'
- os: windows-latest - os: windows-latest
python-version: '3.9' python-version: '3.6'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Display Python version - name: Display Python version
if: ${{ matrix.python-version != 'pypy3.9' }} # Use single quotes in expressions for input `python-version`
run: python --version run: python --version
``` ```
@ -280,35 +240,16 @@ jobs:
`setup-python` action can read Python or PyPy version from a version file. `python-version-file` input is used for specifying the path to the version file. If the file that was supplied to `python-version-file` input doesn't exist, the action will fail with error. `setup-python` action can read Python or PyPy version from a version file. `python-version-file` input is used for specifying the path to the version file. If the file that was supplied to `python-version-file` input doesn't exist, the action will fail with error.
>In case both `python-version` and `python-version-file` inputs are supplied, the `python-version-file` input will be ignored due to its lower priority. The .tool-versions file supports version specifications in accordance with asdf standards, adhering to Semantic Versioning ([semver](https://semver.org)). >In case both `python-version` and `python-version-file` inputs are supplied, the `python-version-file` input will be ignored due to its lower priority.
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version-file: '.python-version' # Read python version from a file .python-version python-version-file: '.python-version' # Read python version from a file .python-version
- run: python my_script.py - run: python my_script.py
``` ```
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version-file: 'pyproject.toml' # Read python version from a file pyproject.toml
- run: python my_script.py
```
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version-file: '.tool-versions' # Read python version from a file .tool-versions
- run: python my_script.py
```
## Check latest version ## Check latest version
The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific `Python or PyPy` version is always used. The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific `Python or PyPy` version is always used.
@ -317,14 +258,14 @@ If `check-latest` is set to `true`, the action first checks if the cached versio
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.7'
check-latest: true check-latest: true
- run: python my_script.py - run: python my_script.py
``` ```
> Setting `check-latest` to `true` impacts performance as downloading `Python or PyPy` versions is slower than using cached versions. > Setting `check-latest` to `true` has performance implications as downloading `Python or PyPy` versions is slower than using cached versions.
## Caching packages ## Caching packages
@ -332,10 +273,10 @@ steps:
**Caching pipenv dependencies:** **Caching pipenv dependencies:**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.9'
cache: 'pipenv' cache: 'pipenv'
- name: Install pipenv - name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
@ -345,25 +286,24 @@ steps:
**Caching poetry dependencies:** **Caching poetry dependencies:**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install poetry - name: Install poetry
run: pipx install poetry run: pipx install poetry
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.9'
cache: 'poetry' cache: 'poetry'
- run: poetry install - run: poetry install
- run: poetry run pytest - run: poetry run pytest
``` ```
>**Note:** If the `setup-python` version does not match the version specified in `pyproject.toml` and the python version in `pyproject.toml` is less than the runner's python version, `poetry install` will default to using the runner's Python version.
**Using a list of file paths to cache dependencies** **Using a list of file paths to cache dependencies**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.9'
cache: 'pipenv' cache: 'pipenv'
cache-dependency-path: | cache-dependency-path: |
server/app/Pipfile.lock server/app/Pipfile.lock
@ -375,10 +315,10 @@ steps:
**Using wildcard patterns to cache dependencies** **Using wildcard patterns to cache dependencies**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.9'
cache: 'pip' cache: 'pip'
cache-dependency-path: '**/requirements-dev.txt' cache-dependency-path: '**/requirements-dev.txt'
- run: pip install -r subdirectory/requirements-dev.txt - run: pip install -r subdirectory/requirements-dev.txt
@ -387,10 +327,10 @@ steps:
**Using a list of wildcard patterns to cache dependencies** **Using a list of wildcard patterns to cache dependencies**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.10'
cache: 'pip' cache: 'pip'
cache-dependency-path: | cache-dependency-path: |
**/setup.cfg **/setup.cfg
@ -402,10 +342,10 @@ steps:
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.13' python-version: '3.11'
cache: 'pip' cache: 'pip'
cache-dependency-path: setup.py cache-dependency-path: setup.py
- run: pip install -e . - run: pip install -e .
@ -418,36 +358,36 @@ steps:
### `python-version` ### `python-version`
Using **python-version** output, it's possible to get the precise Python or PyPy version installed by the action. This output is useful when the input `python-version` is given as a range (e.g. 3.9.0 - 3.12.0, 3.x ), but down the line you need to operate (such as in an `if:` statement) with the exact installed version (e.g. 3.12.0). Using **python-version** output it's possible to get the installed by action Python or PyPy version. This output is useful when the input `python-version` is given as a range (e.g. 3.8.0 - 3.10.0 ), but down in a workflow you need to operate with the exact installed version (e.g. 3.10.1).
```yaml ```yaml
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
id: cp312 id: cp310
with: with:
python-version: "3.9.0 - 3.12.0" python-version: "3.8.0 - 3.10.0"
- run: echo '${{ steps.cp312.outputs.python-version }}' - run: echo '${{ steps.cp310.outputs.python-version }}'
``` ```
### `python-path` ### `python-path`
**python-path** output is available to get the absolute path of the Python or PyPy interpreter executable: **python-path** output is available with the absolute path of the Python or PyPy interpreter executable if you need it:
```yaml ```yaml
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
id: cp313 id: cp310
with: with:
python-version: "3.13" python-version: "3.10"
- run: pipx run --python '${{ steps.cp313.outputs.python-path }}' nox --version - run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version
``` ```
### `cache-hit` ### `cache-hit`
@ -458,13 +398,13 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
id: cp313 id: cp310
with: with:
python-version: "3.13.0" python-version: "3.8.0"
cache: "poetry" cache: "poetry"
- run: echo '${{ steps.cp313.outputs.cache-hit }}' # true if cache-hit occurred on the primary key - run: echo '${{ steps.cp310.outputs.cache-hit }}' # true if cache-hit occured on the primary key
``` ```
## Environment variables ## Environment variables
@ -476,7 +416,7 @@ These environment variables become available after setup-python action execution
| pythonLocation |Contains the absolute path to the folder where the requested version of Python or PyPy is installed| | pythonLocation |Contains the absolute path to the folder where the requested version of Python or PyPy is installed|
| Python_ROOT_DIR | https://cmake.org/cmake/help/latest/module/FindPython.html#module:FindPython | | Python_ROOT_DIR | https://cmake.org/cmake/help/latest/module/FindPython.html#module:FindPython |
| Python2_ROOT_DIR |https://cmake.org/cmake/help/latest/module/FindPython2.html#module:FindPython2| | Python2_ROOT_DIR |https://cmake.org/cmake/help/latest/module/FindPython2.html#module:FindPython2|
| Python3_ROOT_DIR |https://cmake.org/cmake/help/latest/module/FindPython3.html#module:FindPython3| | Python3_ROOT_DIR |https://cmake.org/cmake/help/latest/module/FindPython2.html#module:FindPython3|
## Using `update-environment` flag ## Using `update-environment` flag
@ -484,30 +424,30 @@ The `update-environment` flag defaults to `true`.
With this setting, the action will add/update environment variables (e.g. `PATH`, `PKG_CONFIG_PATH`, `pythonLocation`) for Python or PyPy to just work out of the box. With this setting, the action will add/update environment variables (e.g. `PATH`, `PKG_CONFIG_PATH`, `pythonLocation`) for Python or PyPy to just work out of the box.
If `update-environment` is set to `false`, the action will not add/update environment variables. If `update-environment` is set to `false`, the action will not add/update environment variables.
This can prove useful if you only want the side-effect to ensure that Python or PyPy is installed and rely on the `python-path` output to run the executable. This can prove useful if you want the only side-effect to be to ensure Python or PyPy is installed and rely on the `python-path` output to run executable.
Such a requirement on side-effect could be because you don't want your composite action messing with your user's workflows. Such a requirement on side-effect could be because you don't want your composite action messing with your user's workflows.
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
id: cp313 id: cp310
with: with:
python-version: '3.13' python-version: '3.10'
update-environment: false update-environment: false
- run: ${{ steps.cp313.outputs.python-path }} my_script.py - run: ${{ steps.cp310.outputs.python-path }} my_script.py
``` ```
## Available versions of Python, PyPy and GraalPy ## Available versions of Python and PyPy
### Python ### Python
`setup-python` is able to configure **Python** from two sources: `setup-python` is able to configure **Python** from two sources:
- Preinstalled versions of Python in the tool cache on GitHub-hosted runners. - Preinstalled versions of Python in the tool cache on GitHub-hosted runners.
- For detailed information regarding the available versions of Python that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software). - For detailed information regarding the available versions of Python that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
- For every minor versions of Python, expect only the latest patch to be preinstalled. - For every minor version of Python, expect only the latest patch to be preinstalled.
- If `3.12.1` is installed for example, and `3.12.2` is released, expect `3.12.1` to be removed and replaced by `3.12.2` in the tool cache. - If `3.8.1` is installed for example, and `3.8.2` is released, expect `3.8.1` to be removed and replaced by `3.8.2` in the tool cache.
- If the exact patch version doesn't matter to you, specifying just the major and minor versions will get you the latest preinstalled patch version. In the previous example, the version spec `3.12` will use the `3.12.2` Python version found in the cache. - If the exact patch version doesn't matter to you, specifying just the major and minor versions will get you the latest preinstalled patch version. In the previous example, the version spec `3.8` will use the `3.8.2` Python version found in the cache.
- Use `-dev` instead of a patch number (e.g., `3.14-dev`) to install the latest patch version release for a given minor version, *alpha and beta releases included*. - Use `-dev` instead of a patch number (e.g., `3.11-dev`) to install the latest patch version release for a given minor version, *alpha and beta releases included*.
- Downloadable Python versions from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)). - Downloadable Python versions from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)).
- All available versions are listed in the [version-manifest.json](https://github.com/actions/python-versions/blob/main/versions-manifest.json) file. - All available versions are listed in the [version-manifest.json](https://github.com/actions/python-versions/blob/main/versions-manifest.json) file.
- If there is a specific version of Python that is not available, you can open an issue here - If there is a specific version of Python that is not available, you can open an issue here
@ -521,18 +461,13 @@ Such a requirement on side-effect could be because you don't want your composite
- Preinstalled versions of PyPy in the tool cache on GitHub-hosted runners - Preinstalled versions of PyPy in the tool cache on GitHub-hosted runners
- For detailed information regarding the available versions of PyPy that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software). - For detailed information regarding the available versions of PyPy that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
- For the latest PyPy release, all versions of Python are cached. - For the latest PyPy release, all versions of Python are cached.
- Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy3.10` or `pypy-3.10`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy3.10-v7.3.17` or `pypy-3.10-v7.3.17`. - Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy3.7` or `pypy-3.7`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy3.7-v7.3.3` or `pypy-3.7-v7.3.3`.
- Downloadable PyPy versions from the [official PyPy site](https://downloads.python.org/pypy/). - Downloadable PyPy versions from the [official PyPy site](https://downloads.python.org/pypy/).
- All available versions that we can download are listed in [versions.json](https://downloads.python.org/pypy/versions.json) file. - All available versions that we can download are listed in [versions.json](https://downloads.python.org/pypy/versions.json) file.
- PyPy < 7.3.3 are not available to install on-flight. - PyPy < 7.3.3 are not available to install on-flight.
- If some versions are not available, you can open an issue in https://foss.heptapod.net/pypy/pypy/ - If some versions are not available, you can open an issue in https://foss.heptapod.net/pypy/pypy/
### GraalPy
`setup-python` is able to download GraalPy versions from the [official GraalPy repository](https://github.com/oracle/graalpython).
- All available versions that we can download are listed in [releases](https://github.com/oracle/graalpython/releases).
## Hosted tool cache ## Hosted tool cache
GitHub hosted runners have a tool cache that comes with a few versions of Python + PyPy already installed. This tool cache helps speed up runs and tool setup by not requiring any new downloads. There is an environment variable called `RUNNER_TOOL_CACHE` on each runner that describes the location of the tool cache with Python and PyPy installed. `setup-python` works by taking a specific version of Python or PyPy from this tool cache and adding it to PATH. GitHub hosted runners have a tool cache that comes with a few versions of Python + PyPy already installed. This tool cache helps speed up runs and tool setup by not requiring any new downloads. There is an environment variable called `RUNNER_TOOL_CACHE` on each runner that describes the location of the tool cache with Python and PyPy installed. `setup-python` works by taking a specific version of Python or PyPy from this tool cache and adding it to PATH.
@ -569,11 +504,11 @@ If you have a supported self-hosted runner and you would like to use `setup-pyth
### Linux ### Linux
By default, the runner downloads and installs tools into the folder set up by `RUNNER_TOOL_CACHE` environment variable. The environment variable called `AGENT_TOOLSDIRECTORY` can be set to change this location for Linux self-hosted runners: By default runner downloads and installs tools into the folder set up by `RUNNER_TOOL_CACHE` environment variable. The environment variable called `AGENT_TOOLSDIRECTORY` can be set to change this location for Linux self-hosted runners:
- In the same shell that your runner is using, type `export AGENT_TOOLSDIRECTORY=/path/to/folder`. - In the same shell that your runner is using, type `export AGENT_TOOLSDIRECTORY=/path/to/folder`.
- More permanent way of setting the environment variable is to create an `.env` file in the same directory as your runner and to add `AGENT_TOOLSDIRECTORY=/path/to/folder`. This ensures the variable is always set if your runner is configured as a service. - More permanent way of setting the environment variable is to create an `.env` file in the same directory as your runner and to add `AGENT_TOOLSDIRECTORY=/path/to/folder`. This ensures the variable is always set if your runner is configured as a service.
If you're using a non-default tool cache directory be sure that the user starting the runner has write permission to the new tool cache directory. To check the current user and group that the runner belongs, type `ls -l` inside the runner's root directory. If you're using a non-default tool cache directory be sure that the user starting the runner has write permission to the new tool cache directory. To check the current user and group that the runner belongs type `ls -l` inside the runner's root directory.
The runner can be granted write access to any directory using a few techniques: The runner can be granted write access to any directory using a few techniques:
- The user starting the runner is the owner, and the owner has write permission. - The user starting the runner is the owner, and the owner has write permission.
@ -609,37 +544,27 @@ One quick way to grant access is to change the user and group of `/Users/runner/
### Avoiding rate limit issues ### Avoiding rate limit issues
`setup-python` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Python distributions, `setup-python` downloads distributions from [`actions/python-versions`](https://github.com/actions/python-versions) on github.com (outside of the appliance). These calls to `actions/python-versions` are by default made via unauthenticated requests, which are limited to [60 requests per hour per IP](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting). If more requests are made within the time frame, then the action leverages the `raw API` to retrieve the version-manifest. This approach does not impose a rate limit and hence facilitates unrestricted consumption. This is particularly beneficial for GHES runners, which often share the same IP due to Network Address Translation (NAT), to avoid the quick exhaustion of the unauthenticated rate limit. `setup-python` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Python distributions, `setup-python` downloads distributions from [`actions/python-versions`](https://github.com/actions/python-versions) on github.com (outside of the appliance). These calls to `actions/python-versions` are by default made via unauthenticated requests, which are limited to [60 requests per hour per IP](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting). If more requests are made within the time frame, then you will start to see rate-limit errors during downloading that look like this:
### No access to github.com ##[error]API rate limit exceeded for YOUR_IP. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)
If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information. To get a higher rate limit, you can [generate a personal access token (PAT) on github.com](https://github.com/settings/tokens/new) and pass it as the `token` input for the action. It is important to understand that this needs to be a token from github.com and _not_ from your GHES instance. If you or your colleagues do not yet have a github.com account, you might need to create one.
Here are the steps you need to follow to avoid the rate limit:
## Allow pre-releases 1. Create a PAT on any github.com account by using [this link](https://github.com/settings/tokens/new) after logging into github.com (not your Enterprise instance). This PAT does _not_ need any rights, so make sure all the boxes are unchecked.
2. Store this PAT in the repository / organization where you run your workflow, e.g. as `GH_GITHUB_COM_TOKEN`. You can do this by navigating to your repository -> **Settings** -> **Secrets** -> **Actions** -> **New repository secret**.
3. To use this functionality, you need to use any version newer than `v4.3`. Also, change _python-version_ as needed.
The `allow-prereleases` flag defaults to `false`. ```yml
If `allow-prereleases` is set to `true`, the action will allow falling back to pre-release versions of Python when a matching GA version of Python is not available. - name: Set up Python
This allows for example to simplify reuse of `python-version` as an input of nox for pre-releases of Python by not requiring manipulation of the `3.y-dev` specifier. uses: actions/setup-python@4
For CPython, `allow-prereleases` will only have effect for `x.y` version range (e.g. `3.12`).
Let's say that python 3.12 is not generally available, the following workflow will fallback to the most recent pre-release of python 3.12:
```yaml
jobs:
test:
name: ${{ matrix.os }} / ${{ matrix.python_version }}
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [Ubuntu, Windows, macOS]
python_version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: with:
python-version: "${{ matrix.python_version }}" python-version: 3.8
allow-prereleases: true token: ${{ secrets.GH_GITHUB_COM_TOKEN }}
- run: pipx run nox --error-on-missing-interpreters -s tests-${{ matrix.python_version }}
``` ```
Requests should now be authenticated. To verify that you are getting the higher rate limit, you can call GitHub's [rate limit API](https://docs.github.com/en/rest/rate-limit) from within your workflow ([example](https://github.com/actions/setup-python/pull/443#issuecomment-1206776401)).
### No access to github.com
If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.

View File

@ -60,7 +60,6 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub.
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder - To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
- To comply with the code style, **you need to run the `format` script** - To comply with the code style, **you need to run the `format` script**
- To lint the code, **you need to run the `lint:fix` script**
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build - To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
**Learn more about how to implement tests:** **Learn more about how to implement tests:**

10225
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,16 @@
{ {
"name": "setup-python", "name": "setup-python",
"version": "5.0.0", "version": "4.0.0",
"private": true, "private": true,
"description": "Setup python action", "description": "Setup python action",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts", "build": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts",
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"", "format": "prettier --write \"{,!(node_modules)/**/}*.ts\"",
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check \"**/*.{ts,yml,yaml}\"", "format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"",
"lint": "eslint --config ./.eslintrc.js \"**/*.ts\"", "lint": "echo \"Fake command that does nothing. It is used in reusable workflows\"",
"lint:fix": "eslint --config ./.eslintrc.js \"**/*.ts\" --fix",
"release": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts && git add -f dist/", "release": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts && git add -f dist/",
"test": "jest --runInBand --coverage" "test": "jest --coverage"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -25,31 +24,30 @@
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^4.0.3", "@actions/cache": "^3.0.4",
"@actions/core": "^1.10.0", "@actions/core": "^1.10.0",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.0",
"@actions/glob": "^0.5.0", "@actions/glob": "^0.2.0",
"@actions/http-client": "^2.2.3",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"@actions/tool-cache": "^2.0.1", "@actions/tool-cache": "^1.5.5",
"@iarna/toml": "^3.0.0", "semver": "^7.1.3"
"semver": "^7.6.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.12", "@types/jest": "^27.0.2",
"@types/node": "^20.11.25", "@types/node": "^16.11.25",
"@types/semver": "^7.5.8", "@types/semver": "^7.1.0",
"@typescript-eslint/eslint-plugin": "^5.54.0", "@vercel/ncc": "^0.33.4",
"@typescript-eslint/parser": "^5.54.0", "husky": "^7.0.2",
"@vercel/ncc": "^0.38.3", "jest": "^27.2.5",
"eslint": "^8.57.0", "jest-circus": "^27.2.5",
"eslint-config-prettier": "^8.6.0", "prettier": "^2.0.2",
"eslint-plugin-jest": "^27.9.0", "ts-jest": "^27.0.5",
"eslint-plugin-node": "^11.1.0", "typescript": "^4.2.3"
"jest": "^29.7.0", },
"jest-circus": "^29.7.0", "husky": {
"prettier": "^2.8.4", "skipCI": true,
"ts-jest": "^29.1.2", "hooks": {
"typescript": "^5.4.2" "pre-commit": "npm run build && npm run format-check"
}
} }
} }

View File

@ -1,6 +1,5 @@
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 {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
export enum State { export enum State {
STATE_CACHE_PRIMARY_KEY = 'cache-primary-key', STATE_CACHE_PRIMARY_KEY = 'cache-primary-key',
@ -25,33 +24,24 @@ abstract class CacheDistributor {
public async restoreCache() { public async restoreCache() {
const {primaryKey, restoreKey} = await this.computeKeys(); const {primaryKey, restoreKey} = await this.computeKeys();
if (primaryKey.endsWith('-')) { if (primaryKey.endsWith('-')) {
const file =
this.packageManager === 'pip'
? `${this.cacheDependencyPath
.split('\n')
.join(',')} or ${CACHE_DEPENDENCY_BACKUP_PATH}`
: this.cacheDependencyPath.split('\n').join(',');
throw new Error( throw new Error(
`No file in ${process.cwd()} matched to [${file}], make sure you have checked out the target repository` `No file in ${process.cwd()} matched to [${this.cacheDependencyPath
.split('\n')
.join(',')}], make sure you have checked out the target repository`
); );
} }
const cachePath = await this.getCacheGlobalDirectories(); const cachePath = await this.getCacheGlobalDirectories();
core.saveState(State.CACHE_PATHS, cachePath); core.saveState(State.CACHE_PATHS, cachePath);
let matchedKey: string | undefined;
try {
matchedKey = await cache.restoreCache(cachePath, primaryKey, restoreKey);
} catch (err) {
const message = (err as Error).message;
core.info(`[warning]${message}`);
core.setOutput('cache-hit', false);
return;
}
core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey); core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey);
const matchedKey = await cache.restoreCache(
cachePath,
primaryKey,
restoreKey
);
await this.handleLoadedCache(); await this.handleLoadedCache();
this.handleMatchResult(matchedKey, primaryKey); this.handleMatchResult(matchedKey, primaryKey);

View File

@ -1 +0,0 @@
export const CACHE_DEPENDENCY_BACKUP_PATH = '**/pyproject.toml';

View File

@ -8,14 +8,11 @@ import os from 'os';
import CacheDistributor from './cache-distributor'; import CacheDistributor from './cache-distributor';
import {getLinuxInfo, IS_LINUX, IS_WINDOWS} from '../utils'; import {getLinuxInfo, IS_LINUX, IS_WINDOWS} from '../utils';
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
class PipCache extends CacheDistributor { class PipCache extends CacheDistributor {
private cacheDependencyBackupPath: string = CACHE_DEPENDENCY_BACKUP_PATH;
constructor( constructor(
private pythonVersion: string, private pythonVersion: string,
cacheDependencyPath = '**/requirements.txt' cacheDependencyPath: string = '**/requirements.txt'
) { ) {
super('pip', cacheDependencyPath); super('pip', cacheDependencyPath);
} }
@ -59,19 +56,17 @@ class PipCache extends CacheDistributor {
} }
protected async computeKeys() { protected async computeKeys() {
const hash = const hash = await glob.hashFiles(this.cacheDependencyPath);
(await glob.hashFiles(this.cacheDependencyPath)) ||
(await glob.hashFiles(this.cacheDependencyBackupPath));
let primaryKey = ''; let primaryKey = '';
let restoreKey = ''; let restoreKey = '';
if (IS_LINUX) { if (IS_LINUX) {
const osInfo = await getLinuxInfo(); const osInfo = await getLinuxInfo();
primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${osInfo.osVersion}-${osInfo.osName}-python-${this.pythonVersion}-${this.packageManager}-${hash}`; primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${osInfo.osVersion}-${osInfo.osName}-python-${this.pythonVersion}-${this.packageManager}-${hash}`;
restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${osInfo.osVersion}-${osInfo.osName}-python-${this.pythonVersion}-${this.packageManager}`; restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${osInfo.osVersion}-${osInfo.osName}-python-${this.pythonVersion}-${this.packageManager}`;
} else { } else {
primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-python-${this.pythonVersion}-${this.packageManager}-${hash}`; primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}-${hash}`;
restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-python-${this.pythonVersion}-${this.packageManager}`; restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}`;
} }
return { return {

View File

@ -32,7 +32,7 @@ class PipenvCache extends CacheDistributor {
protected async computeKeys() { protected async computeKeys() {
const hash = await glob.hashFiles(this.patterns); const hash = await glob.hashFiles(this.patterns);
const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-python-${this.pythonVersion}-${this.packageManager}-${hash}`; const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}-${hash}`;
const restoreKey = undefined; const restoreKey = undefined;
return { return {
primaryKey, primaryKey,

Some files were not shown because too many files have changed in this diff Show More