Compare commits

..
129 changed files with 160085 additions and 174813 deletions
+6
View File
@@ -0,0 +1,6 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!src/
+51
View File
@@ -0,0 +1,51 @@
// 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
}
};
+1 -1
View File
@@ -14,4 +14,4 @@ jobs:
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: with:
node-version: '24.x' node-version: '20.x'
+1 -1
View File
@@ -16,4 +16,4 @@ jobs:
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: with:
node-version: '24.x' node-version: '20.x'
+28 -108
View File
@@ -6,7 +6,7 @@ on:
- '**.md' - '**.md'
push: push:
branches: branches:
- main - test-macos-x64-runner
- releases/* - releases/*
paths-ignore: paths-ignore:
- '**.md' - '**.md'
@@ -23,20 +23,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13.14t, 3.14.6t] python-version: [3.13.0t, 3.13.1t, 3.13.2t]
exclude:
- os: windows-11-arm
python-version: 3.13.14t
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@@ -53,20 +44,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13.14t, 3.14.6t] python-version: [3.13.1t, 3.13.2t, 3.13.5t]
exclude:
- os: windows-11-arm
python-version: 3.13.14t
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
id: cache-pipenv id: cache-pipenv
uses: ./ uses: ./
@@ -74,19 +56,9 @@ jobs:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'pipenv' cache: 'pipenv'
- name: Install pipenv - name: Install pipenv
run: python -m pip install --upgrade pip pipenv run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies on Linux/macOS - name: Install dependencies
if: runner.os != 'Windows' run: pipenv install requests
run: |
export PIPENV_PYTHON=$(which python)
pipenv install requests
- name: Install dependencies on Windows
if: runner.os == 'Windows'
run: |
# Remove existing virtualenv if any
python -m pipenv --rm || echo "No existing env"
# Create fresh env using current Python
python -m pipenv install --python $(python -c "import sys; print(sys.executable)") requests
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 }})
@@ -96,17 +68,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13.14, 3.14.6] python-version: [3.13.0, 3.13.1, 3.13.2]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Install poetry - name: Install poetry
run: pipx install poetry run: pipx install poetry
- name: Init pyproject.toml - name: Init pyproject.toml
@@ -128,20 +94,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13.14t, 3.14.6t] python-version: [3.13.0t, 3.13.1t, 3.13.2t]
exclude:
- os: windows-11-arm
python-version: 3.13.14t
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@@ -159,20 +116,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13.14t, 3.14.6t] python-version: [3.13.1t, 3.13.2t, 3.13.5t]
exclude:
- os: windows-11-arm
python-version: 3.13.14t
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
id: cache-pipenv id: cache-pipenv
uses: ./ uses: ./
@@ -181,19 +129,9 @@ jobs:
cache: 'pipenv' cache: 'pipenv'
cache-dependency-path: '**/pipenv-requirements.txt' cache-dependency-path: '**/pipenv-requirements.txt'
- name: Install pipenv - name: Install pipenv
run: python -m pip install --upgrade pip pipenv run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies on Linux/macOS - name: Install dependencies
if: runner.os != 'Windows' run: pipenv install requests
run: |
export PIPENV_PYTHON=$(which python)
pipenv install requests
- name: Install dependencies on Windows
if: runner.os == 'Windows'
run: |
# Remove existing virtualenv if any
python -m pipenv --rm || echo "No existing env"
# Create fresh env using current Python
python -m pipenv install --python $(python -c "import sys; print(sys.executable)") requests
python-pip-dependencies-caching-with-pip-version: python-pip-dependencies-caching-with-pip-version:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}) name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
@@ -203,20 +141,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13.14t, 3.14.6t] python-version: [3.13.0t, 3.13.1t, 3.13.2t]
exclude:
- os: windows-11-arm
python-version: 3.13.14t
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@@ -234,20 +163,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13.14t, 3.14.6t] python-version: [3.13.0t, 3.13.1t, 3.13.2t]
exclude:
- os: windows-11-arm
python-version: 3.13.14t
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
+60 -96
View File
@@ -6,7 +6,7 @@ on:
- '**.md' - '**.md'
push: push:
branches: branches:
- main - test-macos-x64-runner
- releases/* - releases/*
paths-ignore: paths-ignore:
- '**.md' - '**.md'
@@ -23,26 +23,24 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: python-version:
['3.10', '3.11', 'pypy-3.11-v7.x', '3.12', '3.13', '3.14'] [
'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: exclude:
- os: windows-latest - os: windows-latest
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
- os: windows-11-arm
python-version: pypy-3.11-v7.x
- os: windows-11-arm
python-version: '3.10'
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@@ -59,24 +57,23 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: ['3.11', 'pypy-3.11-v7.x', '3.12', '3.13', '3.14'] python-version:
['3.10', 'pypy-3.10-v7.x', '3.11', 'pypy-3.11-v7.x', '3.12', '3.13']
exclude: exclude:
- os: windows-latest - os: windows-latest
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
- os: ubuntu-22.04 - os: ubuntu-22.04
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
- os: windows-11-arm - os: ubuntu-22.04-arm
python-version: pypy-3.10-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.10-v7.x
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
id: cache-pipenv id: cache-pipenv
uses: ./ uses: ./
@@ -111,30 +108,23 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: python-version:
['3.10', '3.11', 'pypy-3.11-v7.x', '3.12', '3.13', '3.14'] [
exclude: '3.9',
- os: windows-latest 'pypy-3.9-v7.x',
python-version: pypy-3.11-v7.x '3.10',
- os: ubuntu-22.04 'pypy-3.10-v7.x',
python-version: pypy-3.11-v7.x '3.11',
- os: windows-11-arm 'pypy-3.11-v7.x',
python-version: pypy-3.11-v7.x '3.12',
- os: windows-11-arm '3.13'
python-version: '3.10' ]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Install poetry - name: Install poetry
run: | run: pipx install poetry
pipx install poetry
- name: Init pyproject.toml - name: Init pyproject.toml
run: mv ./__tests__/data/pyproject.toml . run: mv ./__tests__/data/pyproject.toml .
- name: Setup Python - name: Setup Python
@@ -142,10 +132,6 @@ jobs:
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'poetry' cache: 'poetry'
- name: Bootstrap packaging
run: |
python -m ensurepip --upgrade
python -m pip install --upgrade pip setuptools wheel packaging
- name: Install dependencies - name: Install dependencies
run: poetry install --no-root run: poetry install --no-root
@@ -157,25 +143,24 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: python-version:
['3.10', '3.11', 'pypy-3.11-v7.x', '3.12', '3.13', '3.14'] [
'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: exclude:
- os: windows-latest - os: windows-latest
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
- os: windows-11-arm
python-version: pypy-3.11-v7.x
- os: windows-11-arm
python-version: '3.10'
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@@ -193,24 +178,21 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: ['3.11', 'pypy-3.11-v7.x', '3.12', '3.13', '3.14'] python-version:
['3.10', 'pypy-3.10-v7.x', '3.11', 'pypy-3.11-v7.x', '3.12', '3.13']
exclude: exclude:
- os: windows-latest - os: windows-latest
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
- os: ubuntu-22.04 - os: ubuntu-22.04
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
- os: windows-11-arm - os: ubuntu-22.04-arm
python-version: pypy-3.10-v7.x
- os: ubuntu-22.04-arm
python-version: pypy-3.11-v7.x python-version: pypy-3.11-v7.x
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
id: cache-pipenv id: cache-pipenv
uses: ./ uses: ./
@@ -246,20 +228,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
exclude:
- os: windows-11-arm
python-version: '3.10'
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
@@ -277,20 +250,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
exclude:
- os: windows-11-arm
python-version: '3.10'
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: ./ uses: ./
with: with:
+38 -54
View File
@@ -3,7 +3,7 @@ name: e2e tests
on: on:
push: push:
branches: branches:
- main - test-macos-x64-runner
paths-ignore: paths-ignore:
- '**.md' - '**.md'
pull_request: pull_request:
@@ -19,25 +19,24 @@ jobs:
matrix: matrix:
operating-system: operating-system:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: Run with setup-python 3.9.13
uses: ./
with:
python-version: 3.9.13
- name: Verify 3.9.13
run: python __tests__/verify-python.py 3.9.13
- name: Run with setup-python 3.10.11 - name: Run with setup-python 3.10.11
if: matrix.operating-system != 'windows-11-arm'
uses: ./ uses: ./
with: with:
python-version: 3.10.11 python-version: 3.10.11
- name: Verify 3.10.11 - name: Verify 3.10.11
if: matrix.operating-system != 'windows-11-arm'
run: python __tests__/verify-python.py 3.10.11 run: python __tests__/verify-python.py 3.10.11
- name: Run with setup-python 3.11.9 - name: Run with setup-python 3.11.9
@@ -47,58 +46,43 @@ jobs:
- name: Verify 3.11.9 - name: Verify 3.11.9
run: python __tests__/verify-python.py 3.11.9 run: python __tests__/verify-python.py 3.11.9
- name: Run with setup-python 3.12.10 - name: Run with setup-python 3.12.7
uses: ./ uses: ./
with: with:
python-version: 3.12.10 python-version: 3.12.7
- name: Verify 3.12.10 - name: Verify 3.12.7
run: python __tests__/verify-python.py 3.12.10 run: python __tests__/verify-python.py 3.12.7
- name: Run with setup-python 3.13.14 - name: Run with setup-python 3.13.0
uses: ./ uses: ./
with: with:
python-version: 3.13.14 python-version: 3.13.0
- name: Verify 3.13.14 - name: Verify 3.13.0
run: python __tests__/verify-python.py 3.13.14 run: python __tests__/verify-python.py 3.13.0
- name: Run with setup-python 3.14.6 - name: Run with setup-python 3.13
id: cp313
uses: ./ uses: ./
with: with:
python-version: 3.14.6 python-version: '3.13'
- name: Verify 3.14.6 - name: Verify 3.13
run: python __tests__/verify-python.py 3.14.6
- name: Run with setup-python 3.14
id: cp314
uses: ./
with:
python-version: '3.14'
- name: Verify 3.14
run: python __tests__/verify-python.py 3.14
- name: Install pipx (Windows)
if: runner.os == 'Windows'
run: python -m pip install pipx
- name: Run python-path sample 3.14
run: pipx run --python '${{ steps.cp314.outputs.python-path }}' nox --version
env:
PIPX_HOME: '${{ runner.temp }}/pipx'
PIPX_BIN_DIR: '${{ runner.temp }}/pipx/bin'
- name: Run with setup-python ==3.14
uses: ./
with:
python-version: '==3.14'
- name: Verify ==3.14
run: python __tests__/verify-python.py 3.14
- name: Run with setup-python <3.14
uses: ./
with:
python-version: '<3.14'
- name: Verify <3.14
run: python __tests__/verify-python.py 3.13 run: python __tests__/verify-python.py 3.13
- 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
uses: ./
with:
python-version: '==3.13'
- name: Verify ==3.13
run: python __tests__/verify-python.py 3.13
- name: Run with setup-python <3.13
uses: ./
with:
python-version: '<3.13'
- name: Verify <3.13
run: python __tests__/verify-python.py 3.12
- name: Test Raw Endpoint Access - name: Test Raw Endpoint Access
run: | run: |
@@ -14,7 +14,7 @@ jobs:
steps: steps:
- name: Checking out - name: Checking out
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: Publish - name: Publish
id: publish id: publish
uses: actions/publish-immutable-action@4bc8754ffc40f27910afb20287dbbbb675a4e978 # v0.0.4 uses: actions/publish-immutable-action@v0.0.4
@@ -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.4.0 uses: actions/publish-action@v0.3.0
with: with:
source-tag: ${{ env.TAG_NAME }} source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }} slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
+12 -21
View File
@@ -3,7 +3,7 @@ name: Validate GraalPy e2e
on: on:
push: push:
branches: branches:
- main - test-macos-x64-runner
paths-ignore: paths-ignore:
- '**.md' - '**.md'
pull_request: pull_request:
@@ -20,21 +20,17 @@ jobs:
matrix: matrix:
os: os:
[ [
macos-latest, macos-14-large
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-15-intel
] ]
graalpy: graalpy:
- 'graalpy-22.3'
- 'graalpy-23.0'
- 'graalpy-23.1' - 'graalpy-23.1'
- 'graalpy-24.2' - 'graalpy-24.1'
- 'graalpy-25.0'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.graalpy }} - name: setup-python ${{ matrix.graalpy }}
id: setup-python id: setup-python
@@ -74,18 +70,13 @@ jobs:
matrix: matrix:
os: os:
[ [
macos-latest, macos-14-large
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-15-intel
] ]
graalpy: ['graalpy23.1', 'graalpy24.2', 'graalpy25.0'] graalpy: ['graalpy22.3', 'graalpy23.0', 'graalpy23.1', 'graalpy24.1']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.graalpy }} - name: setup-python ${{ matrix.graalpy }}
id: setup-python id: setup-python
@@ -105,14 +96,14 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, windows-latest, macos-latest, macos-15-intel] os: [macos-14-large]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup GraalPy and check latest - name: Setup GraalPy and check latest
uses: ./ uses: ./
id: graalpy id: graalpy
with: with:
python-version: 'graalpy-25.x' python-version: 'graalpy-24.x'
check-latest: true check-latest: true
- name: GraalPy and Python version - name: GraalPy and Python version
run: python --version run: python --version
+29 -49
View File
@@ -3,7 +3,7 @@ name: Validate PyPy e2e
on: on:
push: push:
branches: branches:
- main - test-macos-x64-runner
paths-ignore: paths-ignore:
- '**.md' - '**.md'
pull_request: pull_request:
@@ -22,24 +22,25 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
macos-15-intel,
macos-latest
] ]
pypy: pypy:
- 'pypy-3.11' - 'pypy-2.7'
- 'pypy-3.11-v7.3.23' - 'pypy-3.10'
- 'pypy-3.11-v7.3.x' - 'pypy3.9'
- 'pypy-3.11-v7.x' - 'pypy-2.7-v7.3.17'
- 'pypy-3.11-nightly' - 'pypy-3.10-v7.3.17'
- 'pypy3.11-v7.3.23' - 'pypy-3.10-v7.3.16'
- 'pypy-3.10-v7.3.x'
- 'pypy-3.10-v7.x'
- 'pypy-2.7-v7.3.12rc1'
- 'pypy-3.10-nightly'
- 'pypy3.10-v7.3.17'
- 'pypy3.11-v7.3.19'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.pypy }} - name: setup-python ${{ matrix.pypy }}
id: setup-python id: setup-python
@@ -78,19 +79,12 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ - macos-14-large
ubuntu-22.04, pypy: ['pypy-2.7', 'pypy-3.10', 'pypy-3.11']
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
macos-15-intel,
macos-latest
]
pypy: ['pypy-3.11']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.pypy }} - name: setup-python ${{ matrix.pypy }}
id: setup-python id: setup-python
@@ -130,18 +124,13 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
macos-15-intel,
macos-latest
] ]
pypy: ['pypy3.11-nightly', 'pypy3.11'] pypy: ['pypy2.7', 'pypy3.9', 'pypy3.10-nightly', 'pypy3.11']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.pypy }} - name: setup-python ${{ matrix.pypy }}
id: setup-python id: setup-python
@@ -163,15 +152,10 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
macos-15-intel,
macos-latest
] ]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup PyPy and check latest - name: Setup PyPy and check latest
uses: ./ uses: ./
with: with:
@@ -204,21 +188,17 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
macos-15-intel,
macos-latest
] ]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- 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.11-v7.3.x
pypy-3.10-v7.3.x pypy-3.10-v7.3.x
pypy3.9
check-latest: true check-latest: true
- name: PyPy and Python version - name: PyPy and Python version
run: python --version run: python --version
@@ -236,13 +216,13 @@ jobs:
run: | run: |
EXECUTABLE="pypy-3.11-v7.3.x" EXECUTABLE="pypy-3.11-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 -* suffix 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='pypy-3.10-v7.3.x' EXECUTABLE='pypy3.9'
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 -* suffix EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
${EXECUTABLE} --version ${EXECUTABLE} --version
shell: bash shell: bash
+51 -209
View File
@@ -3,7 +3,7 @@ name: Validate Python e2e freethread
on: on:
push: push:
branches: branches:
- main - test-macos-x64-runner
paths-ignore: paths-ignore:
- '**.md' - '**.md'
pull_request: pull_request:
@@ -22,18 +22,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14t, 3.14.6t] python: [3.13.0t, 3.13.1t, 3.13.2t]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }} - name: setup-python ${{ matrix.python }}
id: setup-python id: setup-python
@@ -59,18 +53,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14t, 3.14.6t] python: [3.13.0t, 3.13.1t, 3.13.2t]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version run: echo ${{ matrix.python }} > .python-version
@@ -99,18 +87,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14t, 3.14.6t] python: [3.13.0t, 3.13.1t, 3.13.2t]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version run: echo ${{ matrix.python }} > .python-version
@@ -137,18 +119,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14, 3.14.6] python: [3.13.0, 3.13.1, 3.13.2]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: | run: |
@@ -178,18 +154,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14, 3.14.6] python: [3.13.0, 3.13.1, 3.13.2]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: | run: |
@@ -219,18 +189,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14t, 3.14.6t, 3.15t-dev] python: [3.13.0t, 3.13.1t, 3.13.2t, 3.14t-dev]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-tool-versions-file ${{ matrix.python }} - name: build-tool-versions-file ${{ matrix.python }}
run: | run: |
@@ -242,111 +206,25 @@ jobs:
with: with:
python-version-file: .tool-versions python-version-file: .tool-versions
setup-versions-from-pipfile-with-python_version:
name: Setup ${{ matrix.python }} ${{ matrix.os }} Pipfile
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-22.04,
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
]
python: [3.13t, 3.15t-dev]
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: build-version-file ${{ matrix.python }}
run: |
echo '[requires]
python_version = "${{ matrix.python }}"
' > Pipfile
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: Pipfile
- 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-pipfile-with-python_full_version:
name: Setup ${{ matrix.python }} ${{ matrix.os }} .tool-versions file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-22.04,
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
]
python: [3.13.14t, 3.14.6t, 3.15t-dev]
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: build-version-file ${{ matrix.python }}
run: |
echo '[requires]
python_full_version = "${{ matrix.python }}"
' > Pipfile
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: Pipfile
- 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-pre-release-version-from-manifest: setup-pre-release-version-from-manifest:
name: Setup 3.15.0-beta.3 ${{ matrix.os }} name: Setup 3.14.0-alpha.6 ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python 3.15.0-beta.3 - name: setup-python 3.14.0-alpha.6
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.15.0-beta.3' python-version: '3.14.0-alpha.6'
freethreaded: true freethreaded: true
- name: Check python-path - name: Check python-path
@@ -360,67 +238,55 @@ 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.15t-dev ${{ matrix.os }} name: Setup 3.14t-dev ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python 3.15t-dev - name: setup-python 3.14t-dev
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.15t-dev' python-version: '3.14t-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.15.') }} run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash shell: bash
- 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-prerelease-version: setup-prerelease-version:
name: Setup 3.15t ${{ matrix.os }} name: Setup 3.14t ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python 3.15t - name: setup-python 3.14t
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.15t' python-version: '3.14t'
allow-prereleases: true allow-prereleases: true
- name: Check python-path - name: Check python-path
@@ -428,7 +294,7 @@ jobs:
shell: bash shell: bash
- name: Validate version - name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.15.') }} run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash shell: bash
- name: Run simple code - name: Run simple code
@@ -442,18 +308,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14t, 3.14.6t] python: [3.13.0t, 3.13.1t, 3.13.2t]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }} - name: setup-python ${{ matrix.python }}
id: setup-python id: setup-python
@@ -475,17 +335,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: [3.13t, 3.15t-dev] python-version: [3.13t, 3.14t-dev]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python and check latest - name: Setup Python and check latest
id: setup-python id: setup-python
uses: ./ uses: ./
@@ -502,24 +356,18 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup multiple Python versions - name: Setup Python and check latest
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: | python-version: |
3.13.14t 3.13.1t
3.14.6t 3.13.2t
3.15t-dev 3.14t-dev
- name: Verify Python version - name: Verify Python version
run: ${{ steps.setup-python.outputs.python-path }} -VVV run: ${{ steps.setup-python.outputs.python-path }} -VVV
@@ -531,18 +379,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.13.14, 3.14.6, 3.15-dev, 3.15.0-beta.3] python: [3.13.1, 3.13.2, 3.14-dev, 3.14.0-alpha.6]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }} - name: setup-python ${{ matrix.python }}
id: setup-python id: setup-python
uses: ./ uses: ./
+51 -253
View File
@@ -3,7 +3,7 @@ name: Validate Python e2e
on: on:
push: push:
branches: branches:
- main - test-macos-x64-runner
paths-ignore: paths-ignore:
- '**.md' - '**.md'
pull_request: pull_request:
@@ -22,21 +22,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.10.11, 3.11.9, 3.12.10, 3.13.14, 3.14.6] python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
exclude:
- os: windows-11-arm
python: 3.10.11
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }} - name: setup-python ${{ matrix.python }}
id: setup-python id: setup-python
@@ -69,21 +60,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.10.11, 3.11.9, 3.12.10, 3.13.14, 3.14.6] python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
exclude:
- os: windows-11-arm
python: 3.10.11
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version run: echo ${{ matrix.python }} > .python-version
@@ -119,21 +101,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.10.11, 3.11.9, 3.12.10, 3.13.14, 3.14.6] python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
exclude:
- os: windows-11-arm
python: 3.10.11
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version run: echo ${{ matrix.python }} > .python-version
@@ -167,21 +140,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.10.11, 3.11.9, '==3.12.10', 3.13.14, 3.14.6] python: [3.9.13, 3.10.11, 3.11.9, '==3.12.3', 3.13.2]
exclude:
- os: windows-11-arm
python: 3.10.11
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: | run: |
@@ -220,21 +184,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [3.10.11, 3.11.9, 3.12.10, 3.13.14, 3.14.6] python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
exclude:
- os: windows-11-arm
python: 3.10.11
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }} - name: build-version-file ${{ matrix.python }}
run: | run: |
@@ -273,25 +228,15 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: [pypy3.11-7.3.18, graalpy-24.1.2, 3.13.14, 3.15-dev] python: [pypy3.11-7.3.18, graalpy-24.1.2, 3.13.2, 3.14-dev]
exclude: exclude:
- os: windows-latest - os: windows-latest
python: graalpy-24.1.2 python: graalpy-24.1.2
- os: windows-11-arm
python: graalpy-24.1.2
- os: windows-11-arm
python: pypy3.11-7.3.18
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: build-tool-versions-file ${{ matrix.python }} - name: build-tool-versions-file ${{ matrix.python }}
run: | run: |
@@ -303,137 +248,25 @@ jobs:
with: with:
python-version-file: .tool-versions python-version-file: .tool-versions
setup-versions-from-pipfile-with-python_version:
name: Setup ${{ matrix.python }} ${{ matrix.os }} Pipfile with python_version
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-22.04,
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
]
python: [3.10.11, 3.11.9, 3.13.14, 3.14.6]
exclude:
- os: windows-11-arm
python: 3.10.11
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: build-version-file ${{ matrix.python }}
run: |
echo '[requires]
python_version = "${{ matrix.python }}"
' > Pipfile
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: Pipfile
- 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-pipfile-with-python_full_version:
name: Setup ${{ matrix.python }} ${{ matrix.os }} Pipfile with python_full_version
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-22.04,
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
]
python: [3.10.11, 3.11.9, 3.13.14, 3.14.6]
exclude:
- os: windows-11-arm
python: 3.10.11
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: build-version-file ${{ matrix.python }}
run: |
echo '[requires]
python_full_version = "${{ matrix.python }}"
' > Pipfile
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: Pipfile
- 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-pre-release-version-from-manifest: setup-pre-release-version-from-manifest:
name: Setup 3.15.0-beta.3 ${{ matrix.os }} name: Setup 3.14.0-alpha.6 ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python 3.15.0-beta.3 - name: setup-python 3.14.0-alpha.6
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.15.0-beta.3' python-version: '3.14.0-alpha.6'
- 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 }}'
@@ -442,8 +275,8 @@ jobs:
- name: Validate version - name: Validate version
run: | run: |
$pythonVersion = (python --version) $pythonVersion = (python --version)
if ("Python 3.15.0b3" -ne "$pythonVersion"){ if ("Python 3.14.0a6" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is 3.15.0b3" Write-Host "The current version is $pythonVersion; expected version is 3.14.0a6"
exit 1 exit 1
} }
$pythonVersion $pythonVersion
@@ -453,67 +286,55 @@ 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.15-dev ${{ matrix.os }} name: Setup 3.14-dev ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python 3.15-dev - name: setup-python 3.14-dev
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.15-dev' python-version: '3.14-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.15.') }} run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash shell: bash
- 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-prerelease-version: setup-prerelease-version:
name: Setup 3.15 ${{ matrix.os }} name: Setup 3.14 ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python 3.15 - name: setup-python 3.14
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version: '3.15' python-version: '3.14'
allow-prereleases: true allow-prereleases: true
- name: Check python-path - name: Check python-path
@@ -521,7 +342,7 @@ jobs:
shell: bash shell: bash
- name: Validate version - name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.15.') }} run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash shell: bash
- name: Run simple code - name: Run simple code
@@ -535,21 +356,12 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python: ['3.10', '3.11', '3.12', '3.13', '3.14'] python: ['3.9', '3.10', '3.11', '3.12', '3.13']
exclude:
- os: windows-11-arm
python: '3.10'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@v4
- name: setup-python ${{ matrix.python }} - name: setup-python ${{ matrix.python }}
id: setup-python id: setup-python
@@ -571,20 +383,11 @@ jobs:
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
exclude:
- os: windows-11-arm
python-version: '3.10'
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python and check latest - name: Setup Python and check latest
uses: ./ uses: ./
with: with:
@@ -606,31 +409,26 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
[ [
ubuntu-22.04, macos-14-large
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
macos-15-intel,
macos-latest
] ]
steps: steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/checkout@v4
- name: Setup Python and check latest - name: Setup Python and check latest
uses: ./ uses: ./
with: with:
python-version: | python-version: |
3.9
3.10
3.11 3.11
3.12 3.12
3.13 3.13
3.14
check-latest: true check-latest: true
- name: Validate version - name: Validate version
run: | run: |
$pythonVersion = (python --version) $pythonVersion = (python --version)
if ("$pythonVersion" -NotMatch "3.14"){ if ("$pythonVersion" -NotMatch "3.13"){
Write-Host "The current version is $pythonVersion; expected version is 3.14" Write-Host "The current version is $pythonVersion; expected version is 3.13"
exit 1 exit 1
} }
$pythonVersion $pythonVersion
+1 -5
View File
@@ -10,10 +10,6 @@ allowed:
- cc0-1.0 - cc0-1.0
- unlicense - unlicense
- 0bsd - 0bsd
- blueoak-1.0.0
reviewed: reviewed:
npm: npm:
- "@actions/http-client"
- "balanced-match"
- "brace-expansion"
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.
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
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
// 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'
};
-10
View File
@@ -1,10 +0,0 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid"
}
+10 -21
View File
@@ -11,17 +11,6 @@ This action provides the following functionality for GitHub Actions users:
- Optionally caching dependencies for pip, pipenv and poetry - Optionally caching dependencies for pip, pipenv and poetry
- Registering problem matchers for error output - Registering problem matchers for error output
## What's new in V7
- Migrated action internals to ESM for compatibility with latest `@actions/*` packages. No changes to action inputs, outputs, or behavior.
## Breaking changes in V6
- Upgraded action from node20 to node24
> Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. See [Release Notes](https://github.com/actions/runner/releases/tag/v2.327.1)
For more details, see the full release notes on the [releases page](https://github.com/actions/setup-python/releases/tag/v6.0.0)
## Basic usage ## Basic usage
See [action.yml](action.yml) See [action.yml](action.yml)
@@ -29,8 +18,8 @@ See [action.yml](action.yml)
**Python** **Python**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v4
- uses: actions/setup-python@v7 - uses: actions/setup-python@v5
with: with:
python-version: '3.13' python-version: '3.13'
- run: python my_script.py - run: python my_script.py
@@ -39,8 +28,8 @@ steps:
**PyPy** **PyPy**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v4
- uses: actions/setup-python@v7 - uses: actions/setup-python@v5
with: with:
python-version: 'pypy3.10' python-version: 'pypy3.10'
- run: python my_script.py - run: python my_script.py
@@ -49,8 +38,8 @@ steps:
**GraalPy** **GraalPy**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v4
- uses: actions/setup-python@v7 - uses: actions/setup-python@v5
with: with:
python-version: 'graalpy-24.0' python-version: 'graalpy-24.0'
- run: python my_script.py - run: python my_script.py
@@ -59,8 +48,8 @@ steps:
**Free threaded Python** **Free threaded Python**
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v4
- uses: actions/setup-python@v7 - uses: actions/setup-python@v5
with: with:
python-version: '3.13t' python-version: '3.13t'
- run: python my_script.py - run: python my_script.py
@@ -94,8 +83,8 @@ The action defaults to searching for a dependency file (`requirements.txt` or `p
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v4
- uses: actions/setup-python@v7 - uses: actions/setup-python@v5
with: with:
python-version: '3.13' python-version: '3.13'
cache: 'pip' # caching pip dependencies cache: 'pip' # caching pip dependencies
+62 -112
View File
@@ -1,62 +1,10 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {fileURLToPath} from 'url';
import * as path from 'path'; import * as path from 'path';
import * as core from '@actions/core';
const __dirname = path.dirname(fileURLToPath(import.meta.url)); import * as cache from '@actions/cache';
import * as exec from '@actions/exec';
// Mock @actions modules before importing anything that depends on them import * as io from '@actions/io';
jest.unstable_mockModule('@actions/core', () => ({ import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
info: jest.fn(), import {State} from '../src/cache-distributions/cache-distributor';
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
jest.unstable_mockModule('@actions/cache', () => ({
saveCache: jest.fn(),
restoreCache: jest.fn(),
isFeatureAvailable: jest.fn()
}));
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
jest.unstable_mockModule('@actions/io', () => ({
which: jest.fn(),
mkdirP: jest.fn(),
rmRF: jest.fn(),
mv: jest.fn(),
cp: jest.fn()
}));
// Dynamic imports after mocking
const core = await import('@actions/core');
const cache = await import('@actions/cache');
const exec = await import('@actions/exec');
const io = await import('@actions/io');
const {getCacheDistributor} =
await import('../src/cache-distributions/cache-factory.js');
const {State} = await import('../src/cache-distributions/cache-distributor.js');
describe('restore-cache', () => { describe('restore-cache', () => {
const pipFileLockHash = const pipFileLockHash =
@@ -76,38 +24,43 @@ virtualenvs.in-project = true
virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/pypoetry/virtualenvs virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/pypoetry/virtualenvs
`; `;
let infoSpy: jest.Mock; // core spy
let warningSpy: jest.Mock; let infoSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let saveStateSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let getStateSpy: jest.Mock; let saveStateSpy: jest.SpyInstance;
let setOutputSpy: jest.Mock; let getStateSpy: jest.SpyInstance;
let restoreCacheSpy: jest.Mock; let setOutputSpy: jest.SpyInstance;
let getExecOutputSpy: jest.Mock;
let whichSpy: jest.Mock; // cache spy
let restoreCacheSpy: jest.SpyInstance;
// exec spy
let getExecOutputSpy: jest.SpyInstance;
// io spy
let whichSpy: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
process.env['RUNNER_OS'] = process.env['RUNNER_OS'] ?? 'linux'; process.env['RUNNER_OS'] = process.env['RUNNER_OS'] ?? 'linux';
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => undefined); infoSpy.mockImplementation(input => undefined);
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => undefined); warningSpy.mockImplementation(input => undefined);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => undefined); debugSpy.mockImplementation(input => undefined);
saveStateSpy = core.saveState as jest.Mock; saveStateSpy = jest.spyOn(core, 'saveState');
saveStateSpy.mockImplementation(() => undefined); saveStateSpy.mockImplementation(input => undefined);
getStateSpy = core.getState as jest.Mock; getStateSpy = jest.spyOn(core, 'getState');
getStateSpy.mockImplementation(() => undefined); getStateSpy.mockImplementation(input => undefined);
getExecOutputSpy = exec.getExecOutput as jest.Mock; getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
( getExecOutputSpy.mockImplementation((input: string) => {
getExecOutputSpy as jest.Mock<typeof exec.getExecOutput>
).mockImplementation(async (input: string) => {
if (input.includes('pip')) { if (input.includes('pip')) {
return {stdout: 'pip', stderr: '', exitCode: 0}; return {stdout: 'pip', stderr: '', exitCode: 0};
} }
@@ -121,19 +74,17 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
return {stdout: '', stderr: 'Error occured', exitCode: 2}; return {stdout: '', stderr: 'Error occured', exitCode: 2};
}); });
setOutputSpy = core.setOutput as jest.Mock; setOutputSpy = jest.spyOn(core, 'setOutput');
setOutputSpy.mockImplementation(() => undefined); setOutputSpy.mockImplementation(input => undefined);
restoreCacheSpy = cache.restoreCache as jest.Mock; restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
( restoreCacheSpy.mockImplementation(
restoreCacheSpy as jest.Mock<typeof cache.restoreCache> (cachePaths: string[], primaryKey: string, restoreKey?: string) => {
).mockImplementation( return primaryKey;
(cachePaths: string[], primaryKey: string, restoreKey?: string[]) => {
return Promise.resolve(primaryKey);
} }
); );
whichSpy = io.which as jest.Mock; whichSpy = jest.spyOn(io, 'which');
whichSpy.mockImplementation(() => '/path/to/python'); whichSpy.mockImplementation(() => '/path/to/python');
}); });
@@ -212,13 +163,9 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
fileHash, fileHash,
cachePaths cachePaths
) => { ) => {
( restoreCacheSpy.mockImplementation(
restoreCacheSpy as jest.Mock<typeof cache.restoreCache> (cachePaths: string[], primaryKey: string, restoreKey?: string) => {
).mockImplementation( return primaryKey.includes(fileHash) ? primaryKey : '';
(cachePaths: string[], primaryKey: string, restoreKey?: string[]) => {
return Promise.resolve(
primaryKey.includes(fileHash) ? primaryKey : ''
);
} }
); );
@@ -237,18 +184,25 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
); );
} }
const restoredKeys = await Promise.all( const restoredKeys = restoreCacheSpy.mock.results.map(
restoreCacheSpy.mock.results.map(result => result.value) result => result.value
); );
restoredKeys.forEach(restoredKey => { restoredKeys.forEach(restoredKey => {
if (restoredKey) { if (restoredKey) {
const osSegment = if (process.platform === 'linux' && packageManager === 'pip') {
process.platform === 'linux' ? '-20.04-Ubuntu' : ''; expect(infoSpy).toHaveBeenCalledWith(
const versionSuffix = packageManager === 'poetry' ? '-v2' : ''; `Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}-20.04-Ubuntu-python-${pythonVersion}-${packageManager}-${fileHash}`
expect(infoSpy).toHaveBeenCalledWith( );
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}${osSegment}-python-${pythonVersion}-${packageManager}${versionSuffix}-${fileHash}` } else if (packageManager === 'poetry') {
); expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}-python-${pythonVersion}-${packageManager}-v2-${fileHash}`
);
} else {
expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}-python-${pythonVersion}-${packageManager}-${fileHash}`
);
}
} else { } else {
expect(infoSpy).toHaveBeenCalledWith( expect(infoSpy).toHaveBeenCalledWith(
`${packageManager} cache is not found` `${packageManager} cache is not found`
@@ -337,13 +291,9 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
])( ])(
'restored dependencies for %s by primaryKey', 'restored dependencies for %s by primaryKey',
async (packageManager, pythonVersion, dependencyFile, fileHash) => { async (packageManager, pythonVersion, dependencyFile, fileHash) => {
( restoreCacheSpy.mockImplementation(
restoreCacheSpy as jest.Mock<typeof cache.restoreCache> (cachePaths: string[], primaryKey: string, restoreKey?: string) => {
).mockImplementation( return primaryKey !== fileHash && restoreKey ? pipFileLockHash : '';
(cachePaths: string[], primaryKey: string, restoreKey?: string[]) => {
return Promise.resolve(
primaryKey !== fileHash && restoreKey ? pipFileLockHash : ''
);
} }
); );
const cacheDistributor = getCacheDistributor( const cacheDistributor = getCacheDistributor(
+79 -143
View File
@@ -1,61 +1,8 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals'; import * as core from '@actions/core';
import {fileURLToPath} from 'url'; import * as cache from '@actions/cache';
import path from 'path'; import * as exec from '@actions/exec';
import {run} from '../src/cache-save';
const __dirname = path.dirname(fileURLToPath(import.meta.url)); import {State} from '../src/cache-distributions/cache-distributor';
// Mock @actions modules before importing anything that depends on them
jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
class MockValidationError extends Error {
constructor(message: string) {
super(message);
this.name = 'ValidationError';
}
}
jest.unstable_mockModule('@actions/cache', () => ({
saveCache: jest.fn(),
restoreCache: jest.fn(),
isFeatureAvailable: jest.fn(),
ValidationError: MockValidationError,
ReserveCacheError: MockValidationError
}));
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
// Dynamic imports after mocking
const core = await import('@actions/core');
const cache = await import('@actions/cache');
const exec = await import('@actions/exec');
const {run} = await import('../src/cache-save.js');
const {State} = await import('../src/cache-distributions/cache-distributor.js');
describe('run', () => { describe('run', () => {
const pipFileLockHash = const pipFileLockHash =
@@ -67,54 +14,53 @@ describe('run', () => {
const poetryLockHash = const poetryLockHash =
'571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836'; '571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836';
let infoSpy: jest.Mock; // core spy
let warningSpy: jest.Mock; let infoSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let saveStateSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let getStateSpy: jest.Mock; let saveStateSpy: jest.SpyInstance;
let getInputSpy: jest.Mock; let getStateSpy: jest.SpyInstance;
let setFailedSpy: jest.Mock; let getInputSpy: jest.SpyInstance;
let saveCacheSpy: jest.Mock; let setFailedSpy: jest.SpyInstance;
let getExecOutputSpy: jest.Mock;
// cache spy
let saveCacheSpy: jest.SpyInstance;
// exec spy
let getExecOutputSpy: jest.SpyInstance;
let inputs = {} as any; let inputs = {} as any;
beforeEach(() => { beforeEach(() => {
process.env['RUNNER_OS'] = process.env['RUNNER_OS'] ?? 'linux'; process.env['RUNNER_OS'] = process.env['RUNNER_OS'] ?? 'linux';
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => undefined); infoSpy.mockImplementation(input => undefined);
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => undefined); warningSpy.mockImplementation(input => undefined);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => undefined); debugSpy.mockImplementation(input => undefined);
saveStateSpy = core.saveState as jest.Mock; saveStateSpy = jest.spyOn(core, 'saveState');
saveStateSpy.mockImplementation(() => undefined); saveStateSpy.mockImplementation(input => undefined);
getStateSpy = core.getState as jest.Mock; getStateSpy = jest.spyOn(core, 'getState');
(getStateSpy as jest.Mock<typeof core.getState>).mockImplementation( getStateSpy.mockImplementation(input => {
(input: string) => { if (input === State.CACHE_PATHS) {
if (input === State.CACHE_PATHS) { return JSON.stringify([__dirname]);
return JSON.stringify([__dirname]);
}
return requirementsHash;
} }
); return requirementsHash;
});
setFailedSpy = core.setFailed as jest.Mock; setFailedSpy = jest.spyOn(core, 'setFailed');
getInputSpy = core.getInput as jest.Mock; getInputSpy = jest.spyOn(core, 'getInput');
(getInputSpy as jest.Mock<typeof core.getInput>).mockImplementation( getInputSpy.mockImplementation(input => inputs[input]);
(input: string) => inputs[input]
);
getExecOutputSpy = exec.getExecOutput as jest.Mock; getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
( getExecOutputSpy.mockImplementation((input: string) => {
getExecOutputSpy as jest.Mock<typeof exec.getExecOutput>
).mockImplementation(async (input: string) => {
if (input.includes('pip')) { if (input.includes('pip')) {
return {stdout: 'pip', stderr: '', exitCode: 0}; return {stdout: 'pip', stderr: '', exitCode: 0};
} }
@@ -122,7 +68,7 @@ describe('run', () => {
return {stdout: '', stderr: 'Error occured', exitCode: 2}; return {stdout: '', stderr: 'Error occured', exitCode: 2};
}); });
saveCacheSpy = cache.saveCache as jest.Mock; saveCacheSpy = jest.spyOn(cache, 'saveCache');
saveCacheSpy.mockImplementation(() => undefined); saveCacheSpy.mockImplementation(() => undefined);
}); });
@@ -178,17 +124,15 @@ describe('run', () => {
it('saves cache from pip', async () => { it('saves cache from pip', async () => {
inputs['cache'] = 'pip'; inputs['cache'] = 'pip';
inputs['python-version'] = '3.10.0'; inputs['python-version'] = '3.10.0';
(getStateSpy as jest.Mock<typeof core.getState>).mockImplementation( getStateSpy.mockImplementation((name: string) => {
(name: string) => { if (name === State.CACHE_MATCHED_KEY) {
if (name === State.CACHE_MATCHED_KEY) { return requirementsHash;
return requirementsHash; } else if (name === State.CACHE_PATHS) {
} else if (name === State.CACHE_PATHS) { return JSON.stringify([__dirname]);
return JSON.stringify([__dirname]); } else {
} else { return pipFileLockHash;
return pipFileLockHash;
}
} }
); });
await run(); await run();
@@ -207,17 +151,15 @@ 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'; inputs['python-version'] = '3.10.0';
(getStateSpy as jest.Mock<typeof core.getState>).mockImplementation( getStateSpy.mockImplementation((name: string) => {
(name: string) => { if (name === State.CACHE_MATCHED_KEY) {
if (name === State.CACHE_MATCHED_KEY) { return pipFileLockHash;
return pipFileLockHash; } else if (name === State.CACHE_PATHS) {
} else if (name === State.CACHE_PATHS) { return JSON.stringify([__dirname]);
return JSON.stringify([__dirname]); } else {
} else { return requirementsHash;
return requirementsHash;
}
} }
); });
await run(); await run();
@@ -236,17 +178,15 @@ 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'; inputs['python-version'] = '3.10.0';
(getStateSpy as jest.Mock<typeof core.getState>).mockImplementation( getStateSpy.mockImplementation((name: string) => {
(name: string) => { if (name === State.CACHE_MATCHED_KEY) {
if (name === State.CACHE_MATCHED_KEY) { return poetryLockHash;
return poetryLockHash; } else if (name === State.CACHE_PATHS) {
} else if (name === State.CACHE_PATHS) { return JSON.stringify([__dirname]);
return JSON.stringify([__dirname]); } else {
} else { return requirementsHash;
return requirementsHash;
}
} }
); });
await run(); await run();
@@ -265,17 +205,15 @@ 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'; inputs['python-version'] = '3.10.0';
(getStateSpy as jest.Mock<typeof core.getState>).mockImplementation( getStateSpy.mockImplementation((name: string) => {
(name: string) => { if (name === State.STATE_CACHE_PRIMARY_KEY) {
if (name === State.STATE_CACHE_PRIMARY_KEY) { return poetryLockHash;
return poetryLockHash; } else if (name === State.CACHE_PATHS) {
} else if (name === State.CACHE_PATHS) { return JSON.stringify([__dirname]);
return JSON.stringify([__dirname]); } else {
} else { return requirementsHash;
return requirementsHash;
}
} }
); });
saveCacheSpy.mockImplementation(() => { saveCacheSpy.mockImplementation(() => {
return -1; return -1;
@@ -296,17 +234,15 @@ describe('run', () => {
it('saves with error from toolkit, should not fail the workflow', async () => { it('saves with error from toolkit, should not fail the workflow', async () => {
inputs['cache'] = 'npm'; inputs['cache'] = 'npm';
inputs['python-version'] = '3.10.0'; inputs['python-version'] = '3.10.0';
(getStateSpy as jest.Mock<typeof core.getState>).mockImplementation( getStateSpy.mockImplementation((name: string) => {
(name: string) => { if (name === State.STATE_CACHE_PRIMARY_KEY) {
if (name === State.STATE_CACHE_PRIMARY_KEY) { return poetryLockHash;
return poetryLockHash; } else if (name === State.CACHE_PATHS) {
} else if (name === State.CACHE_PATHS) { return JSON.stringify([__dirname]);
return JSON.stringify([__dirname]); } else {
} else { return requirementsHash;
return requirementsHash;
}
} }
); });
saveCacheSpy.mockImplementation(() => { saveCacheSpy.mockImplementation(() => {
throw new cache.ValidationError('Validation failed'); throw new cache.ValidationError('Validation failed');
+1 -1
View File
@@ -5,7 +5,7 @@ name = "pypi"
[packages] [packages]
flake8 = "==6.0.0" flake8 = "==6.0.0"
numpy = "==2.4.6" numpy = "==2.2.4"
[dev-packages] [dev-packages]
+58 -75
View File
@@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "0060d5c4915f1f35aae1f3e9fa6de3f65d1a851e6e33ac57a04665d5d1c796fa" "sha256": "9d0bc7ff1f9078396b19f05bc5cd57894f3783c68f96fa9d623b1ea5a1b168f5"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@@ -35,82 +35,65 @@
}, },
"numpy": { "numpy": {
"hashes": [ "hashes": [
"sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286",
"sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4", "sha256:0d54974f9cf14acf49c60f0f7f4084b6579d24d439453d5fc5805d46a165b542",
"sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", "sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f",
"sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d",
"sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0",
"sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47", "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7",
"sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3",
"sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d", "sha256:218f061d2faa73621fa23d6359442b0fc658d5b9a70801373625d958259eaca3",
"sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", "sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146",
"sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", "sha256:2fa8fa7697ad1646b5c93de1719965844e004fcad23c91228aca1cf0800044a1",
"sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147", "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6",
"sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc",
"sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", "sha256:4ba5054787e89c59c593a4169830ab362ac2bee8a969249dc56e5d7d20ff8df9",
"sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", "sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592",
"sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73", "sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00",
"sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298",
"sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", "sha256:7051ee569db5fbac144335e0f3b9c2337e0c8d5c9fee015f259a5bd70772b7e8",
"sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", "sha256:7716e4a9b7af82c06a2543c53ca476fa0b57e4d760481273e09da04b74ee6ee2",
"sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392",
"sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", "sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb",
"sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8",
"sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd",
"sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", "sha256:8146f3550d627252269ac42ae660281d673eb6f8b32f113538e0cc2a9aed42b9",
"sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8", "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0",
"sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", "sha256:892c10d6a73e0f14935c31229e03325a7b3093fafd6ce0af704be7f894d95687",
"sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662", "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc",
"sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f",
"sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0", "sha256:9eeea959168ea555e556b8188da5fa7831e21d91ce031e95ce23747b7609f8a4",
"sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", "sha256:a0258ad1f44f138b791327961caedffbf9612bfa504ab9597157806faa95194a",
"sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39",
"sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f", "sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4",
"sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", "sha256:a84eda42bd12edc36eb5b53bbcc9b406820d3353f1994b6cfe453a33ff101775",
"sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", "sha256:ab2939cd5bec30a7430cbdb2287b63151b77cf9624de0532d629c9a1c59b1d5c",
"sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd",
"sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", "sha256:adf8c1d66f432ce577d0197dceaac2ac00c0759f573f28516246351c58a85020",
"sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", "sha256:b4adfbbc64014976d2f91084915ca4e626fbf2057fb81af209c1a6d776d23e3d",
"sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538", "sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24",
"sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7",
"sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93", "sha256:bd3ad3b0a40e713fc68f99ecfd07124195333f1e689387c180813f0e94309d6f",
"sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02", "sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba",
"sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", "sha256:cf28633d64294969c019c6df4ff37f5698e8326db68cc2b66576a51fad634880",
"sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c", "sha256:d0f35b19894a9e08639fd60a1ec1978cb7f5f7f1eace62f38dd36be8aecdef4d",
"sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", "sha256:db1f1c22173ac1c58db249ae48aa7ead29f534b9a948bc56828337aa84a32ed6",
"sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", "sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854",
"sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", "sha256:df2f57871a96bbc1b69733cd4c51dc33bea66146b8c63cacbfed73eec0883017",
"sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8",
"sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", "sha256:e642d86b8f956098b564a45e6f6ce68a22c2c97a04f5acd3f221f57b8cb850ae",
"sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", "sha256:e9e0a277bb2eb5d8a7407e14688b85fd8ad628ee4e0c7930415687b6564207a4",
"sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", "sha256:ea2bb7e2ae9e37d96835b3576a4fa4b3a97592fbea8ef7c3587078b0068b8f09",
"sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff",
"sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960",
"sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", "sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee",
"sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8", "sha256:f4162988a360a29af158aeb4a2f4f09ffed6a969c9776f8f3bdee9b06a8ab7e5",
"sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c",
"sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", "sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91"
"sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7",
"sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751",
"sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8",
"sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605",
"sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e",
"sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45",
"sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2",
"sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895",
"sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe",
"sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb",
"sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a",
"sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577",
"sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d",
"sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a",
"sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda",
"sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6",
"sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.11'", "markers": "python_version >= '3.10'",
"version": "==2.4.6" "version": "==2.2.4"
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
File diff suppressed because it is too large Load Diff
+16 -35
View File
@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
[[package]] [[package]]
name = "altgraph" name = "altgraph"
@@ -6,7 +6,6 @@ version = "0.17.4"
description = "Python graph (network) package" description = "Python graph (network) package"
optional = false optional = false
python-versions = "*" python-versions = "*"
groups = ["main"]
files = [ files = [
{file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"}, {file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"},
{file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"},
@@ -18,7 +17,6 @@ version = "4.0.1"
description = "the modular source code checker: pep8 pyflakes and co" description = "the modular source code checker: pep8 pyflakes and co"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
groups = ["main"]
files = [ files = [
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
@@ -35,8 +33,6 @@ version = "8.5.0"
description = "Read metadata from Python packages" description = "Read metadata from Python packages"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"]
markers = "python_version == \"3.9\""
files = [ files = [
{file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"},
{file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"},
@@ -46,12 +42,12 @@ files = [
zipp = ">=3.20" zipp = ">=3.20"
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
cover = ["pytest-cov"] cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"] enabler = ["pytest-enabler (>=2.2)"]
perf = ["ipython"] perf = ["ipython"]
test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] 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"] type = ["pytest-mypy"]
[[package]] [[package]]
@@ -60,8 +56,6 @@ version = "1.16.3"
description = "Mach-O header analysis and editing" description = "Mach-O header analysis and editing"
optional = false optional = false
python-versions = "*" python-versions = "*"
groups = ["main"]
markers = "sys_platform == \"darwin\""
files = [ files = [
{file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"}, {file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"},
{file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"}, {file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"},
@@ -76,7 +70,6 @@ version = "0.6.1"
description = "McCabe checker, plugin for flake8" description = "McCabe checker, plugin for flake8"
optional = false optional = false
python-versions = "*" python-versions = "*"
groups = ["main"]
files = [ files = [
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
@@ -88,7 +81,6 @@ version = "24.2"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"]
files = [ files = [
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
@@ -100,8 +92,6 @@ version = "2024.8.26"
description = "Python PE parsing module" description = "Python PE parsing module"
optional = false optional = false
python-versions = ">=3.6.0" python-versions = ">=3.6.0"
groups = ["main"]
markers = "sys_platform == \"win32\""
files = [ files = [
{file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"}, {file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"},
{file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"}, {file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"},
@@ -113,7 +103,6 @@ version = "2.8.0"
description = "Python style guide checker" description = "Python style guide checker"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
groups = ["main"]
files = [ files = [
{file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
{file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
@@ -125,7 +114,6 @@ version = "2.4.0"
description = "passive checker of Python programs" description = "passive checker of Python programs"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
groups = ["main"]
files = [ files = [
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
@@ -137,7 +125,6 @@ version = "6.10.0"
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."
optional = false optional = false
python-versions = "<3.14,>=3.8" python-versions = "<3.14,>=3.8"
groups = ["main"]
files = [ files = [
{file = "pyinstaller-6.10.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d60fb22859e11483af735aec115fdde09467cdbb29edd9844839f2c920b748c0"}, {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_aarch64.whl", hash = "sha256:46d75359668993ddd98630a3669dc5249f3c446e35239b43bc7f4155bc574748"},
@@ -173,7 +160,6 @@ version = "2025.1"
description = "Community maintained hooks for PyInstaller" description = "Community maintained hooks for PyInstaller"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"]
files = [ files = [
{file = "pyinstaller_hooks_contrib-2025.1-py3-none-any.whl", hash = "sha256:d3c799470cbc0bda60dcc8e6b4ab976777532b77621337f2037f558905e3a8e9"}, {file = "pyinstaller_hooks_contrib-2025.1-py3-none-any.whl", hash = "sha256:d3c799470cbc0bda60dcc8e6b4ab976777532b77621337f2037f558905e3a8e9"},
{file = "pyinstaller_hooks_contrib-2025.1.tar.gz", hash = "sha256:130818f9e9a0a7f2261f1fd66054966a3a50c99d000981c5d1db11d3ad0c6ab2"}, {file = "pyinstaller_hooks_contrib-2025.1.tar.gz", hash = "sha256:130818f9e9a0a7f2261f1fd66054966a3a50c99d000981c5d1db11d3ad0c6ab2"},
@@ -190,8 +176,6 @@ version = "0.2.3"
description = "A (partial) reimplementation of pywin32 using ctypes/cffi" description = "A (partial) reimplementation of pywin32 using ctypes/cffi"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
groups = ["main"]
markers = "sys_platform == \"win32\""
files = [ files = [
{file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"}, {file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"},
{file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"}, {file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"},
@@ -199,24 +183,23 @@ files = [
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "80.9.0" version = "75.3.2"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.8"
groups = ["main"]
files = [ files = [
{file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, {file = "setuptools-75.3.2-py3-none-any.whl", hash = "sha256:90ab613b6583fc02d5369cbca13ea26ea0e182d1df2d943ee9cbe81d4c61add9"},
{file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, {file = "setuptools-75.3.2.tar.gz", hash = "sha256:3c1383e1038b68556a382c1e8ded8887cd20141b0eb5708a6c8d277de49364f5"},
] ]
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] 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)"]
cover = ["pytest-cov"] 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)"] 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)"] enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] 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) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"]
[[package]] [[package]]
name = "zipp" name = "zipp"
@@ -224,22 +207,20 @@ version = "3.20.2"
description = "Backport of pathlib-compatible object wrapper for zip files" description = "Backport of pathlib-compatible object wrapper for zip files"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"]
markers = "python_version == \"3.9\""
files = [ files = [
{file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"},
{file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"},
] ]
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
cover = ["pytest-cov"] cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"] enabler = ["pytest-enabler (>=2.2)"]
test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
type = ["pytest-mypy"] type = ["pytest-mypy"]
[metadata] [metadata]
lock-version = "2.1" lock-version = "2.0"
python-versions = ">=3.9,<3.14" python-versions = ">=3.8,<3.14"
content-hash = "9a14798bf374c540031f893ff18f9b187bd984391e9da99d13c0e6710b7de09e" content-hash = "6db8fff0987f3dadb02cbf0e510a2d04b01ab2dc6d7b0fb32a0e33a8d30b3a58"
+3 -4
View File
@@ -5,14 +5,13 @@ description = ""
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.9,<3.14" python = ">=3.8,<3.14"
flake8 = "^4.0.1" flake8 = "^4.0.1"
pyinstaller = "6.10.0" pyinstaller = "6.10.0"
setuptools = ">=78.1.1"
packaging = ">=22.0,<26"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
+5 -5
View File
@@ -1,12 +1,12 @@
certifi==2024.7.4 certifi==2020.6.20
chardet==3.0.4 chardet==3.0.4
docutils==0.16 docutils==0.16
idna==3.15 idna==2.10
Kivy==2.0.0rc3 Kivy==2.0.0rc3
Kivy-Garden==0.1.4 Kivy-Garden==0.1.4
packaging==20.7 packaging==20.7
pdf2image==1.12.1 pdf2image==1.12.1
Pygments==2.20.0 Pygments==2.6.1
requests==2.33.0 requests==2.32.2
urllib3==2.7.0 urllib3==1.26.19
xlrd==1.2.0 xlrd==1.2.0
+5 -5
View File
@@ -1,6 +1,6 @@
altgraph==0.17.2 altgraph==0.17.2
certifi==2024.7.4 certifi==2020.6.20
chardet==3.0.4 chardet==3.0.4
@@ -8,7 +8,7 @@ docutils==0.16
future==0.18.2; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2' future==0.18.2; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'
idna==3.15 idna==2.9
itsdangerous==1.1.0 itsdangerous==1.1.0
@@ -32,7 +32,7 @@ pefile==2021.9.3; python_full_version >= '3.6.0'
pillow>=10.2.0 pillow>=10.2.0
pygments==2.20.0 pygments==2.6.1
pyinstaller==6.10.0 pyinstaller==6.10.0
@@ -40,8 +40,8 @@ pyparsing==2.4.7; python_version >= '2.6' and python_version not in '3.0, 3.1, 3
pywin32-ctypes==0.2.0 pywin32-ctypes==0.2.0
requests==2.33.0 requests==2.32.2
urllib3==2.7.0 urllib3==1.26.19
xlrd==1.2.0 xlrd==1.2.0
+92 -146
View File
@@ -1,76 +1,27 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {fileURLToPath} from 'url';
import fs from 'fs'; import fs from 'fs';
import * as path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url)); 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 semver from 'semver';
// Mock @actions modules import * as finder from '../src/find-graalpy';
jest.unstable_mockModule('@actions/core', () => ({ import {IGraalPyManifestRelease, IS_WINDOWS} from '../src/utils';
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
jest.unstable_mockModule('@actions/tool-cache', () => ({ import manifestData from './data/graalpy.json';
find: jest.fn(),
findAllVersions: jest.fn(),
downloadTool: jest.fn(),
extractZip: jest.fn(),
extractTar: jest.fn(),
extract7z: jest.fn(),
extractXar: jest.fn(),
cacheDir: jest.fn(),
cacheFile: jest.fn(),
getManifestFromRepo: jest.fn(),
findFromManifest: jest.fn(),
evaluateVersions: jest.fn()
}));
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
// Dynamic imports after mocking
const core = await import('@actions/core');
const tc = await import('@actions/tool-cache');
const exec = await import('@actions/exec');
const finder = await import('../src/find-graalpy.js');
const utils = await import('../src/utils.js');
// Non-mocked imports
import {HttpClient} from '@actions/http-client';
import type * as ifm from '@actions/http-client/lib/interfaces';
import type {IGraalPyManifestRelease} from '../src/utils.js';
import manifestData from './data/graalpy.json' with {type: 'json'};
const architecture = 'x64'; const architecture = 'x64';
const toolDir = path.join(__dirname, 'runner', 'tools'); const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp'); const tempDir = path.join(__dirname, 'runner', 'temp');
/* GraalPy doesn't have a windows release yet */
const describeSkipOnWindows = IS_WINDOWS ? describe.skip : describe;
describe('parseGraalPyVersion', () => { describe('parseGraalPyVersion', () => {
it.each([ it.each([
['graalpy-23', '23'], ['graalpy-23', '23'],
@@ -93,41 +44,39 @@ describe('parseGraalPyVersion', () => {
describe('findGraalPyToolCache', () => { describe('findGraalPyToolCache', () => {
const actualGraalPyVersion = '23.0.0'; const actualGraalPyVersion = '23.0.0';
const graalpyPath = path.join('GraalPy', actualGraalPyVersion, architecture); const graalpyPath = path.join('GraalPy', actualGraalPyVersion, architecture);
let tcFind: jest.Mock; let tcFind: jest.SpyInstance;
let infoSpy: jest.Mock; let infoSpy: jest.SpyInstance;
let warningSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let addPathSpy: jest.Mock; let addPathSpy: jest.SpyInstance;
let exportVariableSpy: jest.Mock; let exportVariableSpy: jest.SpyInstance;
let setOutputSpy: jest.Mock; let setOutputSpy: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
tcFind = tc.find as jest.Mock; tcFind = jest.spyOn(tc, 'find');
(tcFind as jest.Mock<typeof tc.find>).mockImplementation( tcFind.mockImplementation((toolname: string, pythonVersion: string) => {
(toolname: string, pythonVersion: string) => { const semverVersion = new semver.Range(pythonVersion);
const semverVersion = new semver.Range(pythonVersion); return semver.satisfies(actualGraalPyVersion, semverVersion)
return semver.satisfies(actualGraalPyVersion, semverVersion) ? graalpyPath
? graalpyPath : '';
: ''; });
}
);
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => null); infoSpy.mockImplementation(() => null);
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
addPathSpy = core.addPath as jest.Mock; addPathSpy = jest.spyOn(core, 'addPath');
addPathSpy.mockImplementation(() => null); addPathSpy.mockImplementation(() => null);
exportVariableSpy = core.exportVariable as jest.Mock; exportVariableSpy = jest.spyOn(core, 'exportVariable');
exportVariableSpy.mockImplementation(() => null); exportVariableSpy.mockImplementation(() => null);
setOutputSpy = core.setOutput as jest.Mock; setOutputSpy = jest.spyOn(core, 'setOutput');
setOutputSpy.mockImplementation(() => null); setOutputSpy.mockImplementation(() => null);
}); });
@@ -159,75 +108,74 @@ describe('findGraalPyToolCache', () => {
}); });
}); });
describe('findGraalPyVersion', () => { describeSkipOnWindows('findGraalPyVersion', () => {
let getBooleanInputSpy: jest.Mock; let getBooleanInputSpy: jest.SpyInstance;
let warningSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let infoSpy: jest.Mock; let infoSpy: jest.SpyInstance;
let addPathSpy: jest.Mock; let addPathSpy: jest.SpyInstance;
let exportVariableSpy: jest.Mock; let exportVariableSpy: jest.SpyInstance;
let setOutputSpy: jest.Mock; let setOutputSpy: jest.SpyInstance;
let tcFind: jest.Mock; let tcFind: jest.SpyInstance;
let spyExtractZip: jest.Mock; let spyExtractZip: jest.SpyInstance;
let spyExtractTar: jest.Mock; let spyExtractTar: jest.SpyInstance;
let spyHttpClient: jest.SpiedFunction<typeof HttpClient.prototype.getJson>; let spyHttpClient: jest.SpyInstance;
let spyExistsSync: jest.SpiedFunction<typeof fs.existsSync>; let spyExistsSync: jest.SpyInstance;
let spyExec: jest.Mock; let spyExec: jest.SpyInstance;
let spySymlinkSync: jest.SpiedFunction<typeof fs.symlinkSync>; let spySymlinkSync: jest.SpyInstance;
let spyDownloadTool: jest.Mock; let spyDownloadTool: jest.SpyInstance;
let spyFsReadDir: jest.SpiedFunction<typeof fs.readdirSync>; let spyFsReadDir: jest.SpyInstance;
let spyCacheDir: jest.Mock; let spyCacheDir: jest.SpyInstance;
let spyChmodSync: jest.SpiedFunction<typeof fs.chmodSync>; let spyChmodSync: jest.SpyInstance;
let spyCoreAddPath: jest.Mock; let spyCoreAddPath: jest.SpyInstance;
let spyCoreExportVariable: jest.Mock; let spyCoreExportVariable: jest.SpyInstance;
const env = process.env; const env = process.env;
beforeEach(() => { beforeEach(() => {
getBooleanInputSpy = core.getBooleanInput as jest.Mock; getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(() => false); getBooleanInputSpy.mockImplementation(() => false);
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {}); infoSpy.mockImplementation(() => {});
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
addPathSpy = core.addPath as jest.Mock; addPathSpy = jest.spyOn(core, 'addPath');
addPathSpy.mockImplementation(() => null); addPathSpy.mockImplementation(() => null);
exportVariableSpy = core.exportVariable as jest.Mock; exportVariableSpy = jest.spyOn(core, 'exportVariable');
exportVariableSpy.mockImplementation(() => null); exportVariableSpy.mockImplementation(() => null);
setOutputSpy = core.setOutput as jest.Mock; setOutputSpy = jest.spyOn(core, 'setOutput');
setOutputSpy.mockImplementation(() => null); setOutputSpy.mockImplementation(() => null);
jest.resetModules();
process.env = {...env}; process.env = {...env};
tcFind = tc.find as jest.Mock; tcFind = jest.spyOn(tc, 'find');
(tcFind as jest.Mock<typeof tc.find>).mockImplementation( tcFind.mockImplementation((tool: string, version: string) => {
(tool: string, version: string) => { const semverRange = new semver.Range(version);
const semverRange = new semver.Range(version); let graalpyPath = '';
let graalpyPath = ''; if (semver.satisfies('23.0.0', semverRange)) {
if (semver.satisfies('23.0.0', semverRange)) { graalpyPath = path.join(toolDir, 'GraalPy', '23.0.0', architecture);
graalpyPath = path.join(toolDir, 'GraalPy', '23.0.0', architecture);
}
return graalpyPath;
} }
); return graalpyPath;
});
spyDownloadTool = tc.downloadTool as jest.Mock; spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'GraalPy')); spyDownloadTool.mockImplementation(() => path.join(tempDir, 'GraalPy'));
spyExtractZip = tc.extractZip as jest.Mock; spyExtractZip = jest.spyOn(tc, 'extractZip');
spyExtractZip.mockImplementation(() => tempDir); spyExtractZip.mockImplementation(() => tempDir);
spyExtractTar = tc.extractTar as jest.Mock; spyExtractTar = jest.spyOn(tc, 'extractTar');
spyExtractTar.mockImplementation(() => tempDir); spyExtractTar.mockImplementation(() => tempDir);
spyFsReadDir = jest.spyOn(fs, 'readdirSync'); spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation(() => ['GraalPyTest'] as any); spyFsReadDir.mockImplementation((directory: string) => ['GraalPyTest']);
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation( spyHttpClient.mockImplementation(
@@ -241,7 +189,7 @@ describe('findGraalPyVersion', () => {
} }
); );
spyExec = exec.exec as jest.Mock; spyExec = jest.spyOn(exec, 'exec');
spyExec.mockImplementation(() => undefined); spyExec.mockImplementation(() => undefined);
spySymlinkSync = jest.spyOn(fs, 'symlinkSync'); spySymlinkSync = jest.spyOn(fs, 'symlinkSync');
@@ -250,9 +198,9 @@ describe('findGraalPyVersion', () => {
spyExistsSync = jest.spyOn(fs, 'existsSync'); spyExistsSync = jest.spyOn(fs, 'existsSync');
spyExistsSync.mockReturnValue(true); spyExistsSync.mockReturnValue(true);
spyCoreAddPath = core.addPath as jest.Mock; spyCoreAddPath = jest.spyOn(core, 'addPath');
spyCoreExportVariable = core.exportVariable as jest.Mock; spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
}); });
afterEach(() => { afterEach(() => {
@@ -290,7 +238,7 @@ describe('findGraalPyVersion', () => {
}); });
it('found and install successfully', async () => { it('found and install successfully', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.0.0', architecture) path.join(toolDir, 'GraalPy', '23.0.0', architecture)
); );
@@ -317,7 +265,7 @@ describe('findGraalPyVersion', () => {
}); });
it('found and install successfully without environment update', async () => { it('found and install successfully without environment update', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.0.0', architecture) path.join(toolDir, 'GraalPy', '23.0.0', architecture)
); );
@@ -365,7 +313,7 @@ describe('findGraalPyVersion', () => {
}); });
it('check-latest enabled version found and install successfully', async () => { it('check-latest enabled version found and install successfully', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.0.0', architecture) path.join(toolDir, 'GraalPy', '23.0.0', architecture)
); );
@@ -384,16 +332,14 @@ describe('findGraalPyVersion', () => {
}); });
it('check-latest enabled version is not found and used from toolcache', async () => { it('check-latest enabled version is not found and used from toolcache', async () => {
(tcFind as jest.Mock<typeof tc.find>).mockImplementationOnce( tcFind.mockImplementationOnce((tool: string, version: string) => {
(tool: string, version: string) => { const semverRange = new semver.Range(version);
const semverRange = new semver.Range(version); let graalpyPath = '';
let graalpyPath = ''; if (semver.satisfies('22.3.4', semverRange)) {
if (semver.satisfies('22.3.4', semverRange)) { graalpyPath = path.join(toolDir, 'GraalPy', '22.3.4', architecture);
graalpyPath = path.join(toolDir, 'GraalPy', '22.3.4', architecture);
}
return graalpyPath;
} }
); return graalpyPath;
});
await expect( await expect(
finder.findGraalPyVersion( finder.findGraalPyVersion(
'graalpy-22.3.4', 'graalpy-22.3.4',
@@ -410,15 +356,15 @@ describe('findGraalPyVersion', () => {
}); });
it('found and install successfully, pre-release fallback', async () => { it('found and install successfully, pre-release fallback', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '24.1', architecture) path.join(toolDir, 'GraalPy', '23.1', architecture)
); );
spyChmodSync = jest.spyOn(fs, 'chmodSync'); spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
finder.findGraalPyVersion( finder.findGraalPyVersion(
'graalpy24.1', 'graalpy23.1',
architecture, architecture,
false, false,
false, false,
@@ -426,7 +372,7 @@ describe('findGraalPyVersion', () => {
) )
).rejects.toThrow(); ).rejects.toThrow();
await expect( await expect(
finder.findGraalPyVersion('graalpy24.1', architecture, false, false, true) finder.findGraalPyVersion('graalpy23.1', architecture, false, false, true)
).resolves.toEqual('24.1.0-ea.9'); ).resolves.toEqual('23.1.0-a.1');
}); });
}); });
+98 -160
View File
@@ -1,83 +1,23 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {fileURLToPath} from 'url';
import fs from 'fs'; import fs from 'fs';
import * as path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url)); import * as utils from '../src/utils';
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 semver from 'semver';
// Mock @actions modules import * as finder from '../src/find-pypy';
jest.unstable_mockModule('@actions/core', () => ({ import {
info: jest.fn(), IPyPyManifestRelease,
warning: jest.fn(), IS_WINDOWS,
debug: jest.fn(), getPyPyVersionFromPath
error: jest.fn(), } from '../src/utils';
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
jest.unstable_mockModule('@actions/tool-cache', () => ({ import manifestData from './data/pypy.json';
find: jest.fn(),
findAllVersions: jest.fn(),
downloadTool: jest.fn(),
extractZip: jest.fn(),
extractTar: jest.fn(),
extract7z: jest.fn(),
extractXar: jest.fn(),
cacheDir: jest.fn(),
cacheFile: jest.fn(),
getManifestFromRepo: jest.fn(),
findFromManifest: jest.fn(),
evaluateVersions: jest.fn()
}));
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
// Import real utils BEFORE mock registration to get real function references
const realUtils = await import('../src/utils.js');
// Mock local utils module for readExactPyPyVersionFile/writeExactPyPyVersionFile
jest.unstable_mockModule('../src/utils.js', () => ({
...realUtils,
readExactPyPyVersionFile: jest.fn(),
writeExactPyPyVersionFile: jest.fn()
}));
// Dynamic imports after mocking
const core = await import('@actions/core');
const tc = await import('@actions/tool-cache');
const exec = await import('@actions/exec');
const utils = await import('../src/utils.js');
const finder = await import('../src/find-pypy.js');
// Non-mocked imports
import {HttpClient} from '@actions/http-client';
import type * as ifm from '@actions/http-client/lib/interfaces';
import type {IPyPyManifestRelease} from '../src/utils.js';
import manifestData from './data/pypy.json' with {type: 'json'};
const IS_WINDOWS = utils.IS_WINDOWS;
const getPyPyVersionFromPath = utils.getPyPyVersionFromPath;
let architecture: string; let architecture: string;
@@ -139,45 +79,43 @@ describe('findPyPyToolCache', () => {
const actualPythonVersion = '3.6.17'; const actualPythonVersion = '3.6.17';
const actualPyPyVersion = '7.5.4'; const actualPyPyVersion = '7.5.4';
const pypyPath = path.join('PyPy', actualPythonVersion, architecture); const pypyPath = path.join('PyPy', actualPythonVersion, architecture);
let tcFind: jest.Mock; let tcFind: jest.SpyInstance;
let spyReadExactPyPyVersion: jest.Mock; let spyReadExactPyPyVersion: jest.SpyInstance;
let infoSpy: jest.Mock; let infoSpy: jest.SpyInstance;
let warningSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let addPathSpy: jest.Mock; let addPathSpy: jest.SpyInstance;
let exportVariableSpy: jest.Mock; let exportVariableSpy: jest.SpyInstance;
let setOutputSpy: jest.Mock; let setOutputSpy: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
tcFind = tc.find as jest.Mock; tcFind = jest.spyOn(tc, 'find');
(tcFind as jest.Mock<typeof tc.find>).mockImplementation( tcFind.mockImplementation((toolname: string, pythonVersion: string) => {
(toolname: string, pythonVersion: string) => { const semverVersion = new semver.Range(pythonVersion);
const semverVersion = new semver.Range(pythonVersion); return semver.satisfies(actualPythonVersion, semverVersion)
return semver.satisfies(actualPythonVersion, semverVersion) ? pypyPath
? pypyPath : '';
: ''; });
}
);
spyReadExactPyPyVersion = utils.readExactPyPyVersionFile as jest.Mock; spyReadExactPyPyVersion = jest.spyOn(utils, 'readExactPyPyVersionFile');
spyReadExactPyPyVersion.mockImplementation(() => actualPyPyVersion); spyReadExactPyPyVersion.mockImplementation(() => actualPyPyVersion);
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => null); infoSpy.mockImplementation(() => null);
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
addPathSpy = core.addPath as jest.Mock; addPathSpy = jest.spyOn(core, 'addPath');
addPathSpy.mockImplementation(() => null); addPathSpy.mockImplementation(() => null);
exportVariableSpy = core.exportVariable as jest.Mock; exportVariableSpy = jest.spyOn(core, 'exportVariable');
exportVariableSpy.mockImplementation(() => null); exportVariableSpy.mockImplementation(() => null);
setOutputSpy = core.setOutput as jest.Mock; setOutputSpy = jest.spyOn(core, 'setOutput');
setOutputSpy.mockImplementation(() => null); setOutputSpy.mockImplementation(() => null);
}); });
@@ -221,82 +159,84 @@ describe('findPyPyToolCache', () => {
}); });
describe('findPyPyVersion', () => { describe('findPyPyVersion', () => {
let getBooleanInputSpy: jest.Mock; let getBooleanInputSpy: jest.SpyInstance;
let warningSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let infoSpy: jest.Mock; let infoSpy: jest.SpyInstance;
let addPathSpy: jest.Mock; let addPathSpy: jest.SpyInstance;
let exportVariableSpy: jest.Mock; let exportVariableSpy: jest.SpyInstance;
let setOutputSpy: jest.Mock; let setOutputSpy: jest.SpyInstance;
let tcFind: jest.Mock; let tcFind: jest.SpyInstance;
let spyExtractZip: jest.Mock; let spyExtractZip: jest.SpyInstance;
let spyExtractTar: jest.Mock; let spyExtractTar: jest.SpyInstance;
let spyHttpClient: jest.SpiedFunction<typeof HttpClient.prototype.getJson>; let spyHttpClient: jest.SpyInstance;
let spyExistsSync: jest.SpiedFunction<typeof fs.existsSync>; let spyExistsSync: jest.SpyInstance;
let spyExec: jest.Mock; let spyExec: jest.SpyInstance;
let spySymlinkSync: jest.SpiedFunction<typeof fs.symlinkSync>; let spySymlinkSync: jest.SpyInstance;
let spyDownloadTool: jest.Mock; let spyDownloadTool: jest.SpyInstance;
let spyReadExactPyPyVersion: jest.Mock; let spyReadExactPyPyVersion: jest.SpyInstance;
let spyFsReadDir: jest.SpiedFunction<typeof fs.readdirSync>; let spyFsReadDir: jest.SpyInstance;
let spyWriteExactPyPyVersionFile: jest.Mock; let spyWriteExactPyPyVersionFile: jest.SpyInstance;
let spyCacheDir: jest.Mock; let spyCacheDir: jest.SpyInstance;
let spyChmodSync: jest.SpiedFunction<typeof fs.chmodSync>; let spyChmodSync: jest.SpyInstance;
let spyCoreAddPath: jest.Mock; let spyCoreAddPath: jest.SpyInstance;
let spyCoreExportVariable: jest.Mock; let spyCoreExportVariable: jest.SpyInstance;
const env = process.env; const env = process.env;
beforeEach(() => { beforeEach(() => {
getBooleanInputSpy = core.getBooleanInput as jest.Mock; getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(() => false); getBooleanInputSpy.mockImplementation(() => false);
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {}); infoSpy.mockImplementation(() => {});
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
addPathSpy = core.addPath as jest.Mock; addPathSpy = jest.spyOn(core, 'addPath');
addPathSpy.mockImplementation(() => null); addPathSpy.mockImplementation(() => null);
exportVariableSpy = core.exportVariable as jest.Mock; exportVariableSpy = jest.spyOn(core, 'exportVariable');
exportVariableSpy.mockImplementation(() => null); exportVariableSpy.mockImplementation(() => null);
setOutputSpy = core.setOutput as jest.Mock; setOutputSpy = jest.spyOn(core, 'setOutput');
setOutputSpy.mockImplementation(() => null); setOutputSpy.mockImplementation(() => null);
jest.resetModules();
process.env = {...env}; process.env = {...env};
tcFind = tc.find as jest.Mock; tcFind = jest.spyOn(tc, 'find');
(tcFind as jest.Mock<typeof tc.find>).mockImplementation( tcFind.mockImplementation((tool: string, version: string) => {
(tool: string, version: string) => { const semverRange = new semver.Range(version);
const semverRange = new semver.Range(version); let pypyPath = '';
let pypyPath = ''; if (semver.satisfies('3.6.12', semverRange)) {
if (semver.satisfies('3.6.12', semverRange)) { pypyPath = path.join(toolDir, 'PyPy', '3.6.12', architecture);
pypyPath = path.join(toolDir, 'PyPy', '3.6.12', architecture);
}
return pypyPath;
} }
); return pypyPath;
});
spyWriteExactPyPyVersionFile = utils.writeExactPyPyVersionFile as jest.Mock; spyWriteExactPyPyVersionFile = jest.spyOn(
utils,
'writeExactPyPyVersionFile'
);
spyWriteExactPyPyVersionFile.mockImplementation(() => null); spyWriteExactPyPyVersionFile.mockImplementation(() => null);
spyReadExactPyPyVersion = utils.readExactPyPyVersionFile as jest.Mock; spyReadExactPyPyVersion = jest.spyOn(utils, 'readExactPyPyVersionFile');
spyReadExactPyPyVersion.mockImplementation(() => '7.3.3'); spyReadExactPyPyVersion.mockImplementation(() => '7.3.3');
spyDownloadTool = tc.downloadTool as jest.Mock; spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'PyPy')); spyDownloadTool.mockImplementation(() => path.join(tempDir, 'PyPy'));
spyExtractZip = tc.extractZip as jest.Mock; spyExtractZip = jest.spyOn(tc, 'extractZip');
spyExtractZip.mockImplementation(() => tempDir); spyExtractZip.mockImplementation(() => tempDir);
spyExtractTar = tc.extractTar as jest.Mock; spyExtractTar = jest.spyOn(tc, 'extractTar');
spyExtractTar.mockImplementation(() => tempDir); spyExtractTar.mockImplementation(() => tempDir);
spyFsReadDir = jest.spyOn(fs, 'readdirSync'); spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation(() => ['PyPyTest'] as any); spyFsReadDir.mockImplementation((directory: string) => ['PyPyTest']);
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation( spyHttpClient.mockImplementation(
@@ -310,7 +250,7 @@ describe('findPyPyVersion', () => {
} }
); );
spyExec = exec.exec as jest.Mock; spyExec = jest.spyOn(exec, 'exec');
spyExec.mockImplementation(() => undefined); spyExec.mockImplementation(() => undefined);
spySymlinkSync = jest.spyOn(fs, 'symlinkSync'); spySymlinkSync = jest.spyOn(fs, 'symlinkSync');
@@ -319,9 +259,9 @@ describe('findPyPyVersion', () => {
spyExistsSync = jest.spyOn(fs, 'existsSync'); spyExistsSync = jest.spyOn(fs, 'existsSync');
spyExistsSync.mockReturnValue(true); spyExistsSync.mockReturnValue(true);
spyCoreAddPath = core.addPath as jest.Mock; spyCoreAddPath = jest.spyOn(core, 'addPath');
spyCoreExportVariable = core.exportVariable as jest.Mock; spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
}); });
afterEach(() => { afterEach(() => {
@@ -368,7 +308,7 @@ describe('findPyPyVersion', () => {
}); });
it('found and install successfully', async () => { it('found and install successfully', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.7.7', architecture) path.join(toolDir, 'PyPy', '3.7.7', architecture)
); );
@@ -398,7 +338,7 @@ describe('findPyPyVersion', () => {
}); });
it('found and install successfully without environment update', async () => { it('found and install successfully without environment update', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.7.7', architecture) path.join(toolDir, 'PyPy', '3.7.7', architecture)
); );
@@ -454,7 +394,7 @@ describe('findPyPyVersion', () => {
}); });
it('check-latest enabled version found and install successfully', async () => { it('check-latest enabled version found and install successfully', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.7.7', architecture) path.join(toolDir, 'PyPy', '3.7.7', architecture)
); );
@@ -478,16 +418,14 @@ describe('findPyPyVersion', () => {
}); });
it('check-latest enabled version is not found and used from toolcache', async () => { it('check-latest enabled version is not found and used from toolcache', async () => {
(tcFind as jest.Mock<typeof tc.find>).mockImplementationOnce( tcFind.mockImplementationOnce((tool: string, version: string) => {
(tool: string, version: string) => { const semverRange = new semver.Range(version);
const semverRange = new semver.Range(version); let pypyPath = '';
let pypyPath = ''; if (semver.satisfies('3.8.8', semverRange)) {
if (semver.satisfies('3.8.8', semverRange)) { pypyPath = path.join(toolDir, 'PyPy', '3.8.8', architecture);
pypyPath = path.join(toolDir, 'PyPy', '3.8.8', architecture);
}
return pypyPath;
} }
); return pypyPath;
});
await expect( await expect(
finder.findPyPyVersion( finder.findPyPyVersion(
'pypy-3.8-v7.3.x', 'pypy-3.8-v7.3.x',
@@ -507,7 +445,7 @@ describe('findPyPyVersion', () => {
}); });
it('found and install successfully, pre-release fallback', async () => { it('found and install successfully, pre-release fallback', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.8.12', architecture) path.join(toolDir, 'PyPy', '3.8.12', architecture)
); );
+1 -2
View File
@@ -1,5 +1,4 @@
import {describe, it, expect} from '@jest/globals'; import {desugarVersion, pythonVersionToSemantic} from '../src/find-python';
import {desugarVersion, pythonVersionToSemantic} from '../src/find-python.js';
describe('desugarVersion', () => { describe('desugarVersion', () => {
it.each([ it.each([
+59 -97
View File
@@ -1,12 +1,8 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {fileURLToPath} from 'url';
import * as io from '@actions/io'; import * as io from '@actions/io';
import os from 'os'; import os from 'os';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const toolDir = path.join( const toolDir = path.join(
__dirname, __dirname,
'runner', 'runner',
@@ -23,78 +19,26 @@ const tempDir = path.join(
process.env['RUNNER_TOOL_CACHE'] = toolDir; process.env['RUNNER_TOOL_CACHE'] = toolDir;
process.env['RUNNER_TEMP'] = tempDir; process.env['RUNNER_TEMP'] = tempDir;
// Mock @actions modules import * as tc from '@actions/tool-cache';
jest.unstable_mockModule('@actions/core', () => ({ import * as core from '@actions/core';
info: jest.fn(), import * as finder from '../src/find-python';
warning: jest.fn(), import * as installer from '../src/install-python';
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
// Pre-import real @actions/tool-cache before any mocks import manifestData from './data/versions-manifest.json';
const realTc = await import('@actions/tool-cache');
jest.unstable_mockModule('@actions/tool-cache', () => ({
...realTc,
find: jest.fn(realTc.find),
getManifestFromRepo: jest.fn()
}));
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
// Pre-import real install-python AFTER all its dependency mocks are registered
// so it captures the mocked @actions/tool-cache, @actions/core, @actions/exec
const realInstaller = await import('../src/install-python.js');
// Mock local install-python module - keep real getManifest/findReleaseFromManifest
jest.unstable_mockModule('../src/install-python.js', () => ({
...realInstaller,
installCpythonFromRelease: jest.fn()
}));
// Dynamic imports after mocking
const core = await import('@actions/core');
const tc = await import('@actions/tool-cache');
const finder = await import('../src/find-python.js');
const installer = await import('../src/install-python.js');
import manifestData from './data/versions-manifest.json' with {type: 'json'};
describe('Finder tests', () => { describe('Finder tests', () => {
let writeSpy: jest.SpiedFunction<typeof process.stdout.write>; let writeSpy: jest.SpyInstance;
let spyCoreAddPath: jest.Mock; let spyCoreAddPath: jest.SpyInstance;
let spyCoreExportVariable: jest.Mock; let spyCoreExportVariable: jest.SpyInstance;
const env = process.env; const env = process.env;
beforeEach(() => { beforeEach(() => {
writeSpy = jest.spyOn(process.stdout, 'write'); writeSpy = jest.spyOn(process.stdout, 'write');
writeSpy.mockImplementation(() => true); writeSpy.mockImplementation(() => {});
jest.resetModules();
process.env = {...env}; process.env = {...env};
spyCoreAddPath = core.addPath as jest.Mock; spyCoreAddPath = jest.spyOn(core, 'addPath');
spyCoreExportVariable = core.exportVariable as jest.Mock; spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
// Restore real tc.find default (cleared by jest.resetAllMocks)
(tc.find as jest.Mock).mockImplementation(realTc.find as any);
}); });
afterEach(() => { afterEach(() => {
@@ -105,8 +49,8 @@ describe('Finder tests', () => {
}); });
it('Finds Python if it is installed', async () => { it('Finds Python if it is installed', async () => {
const getBooleanInputSpy = core.getBooleanInput as jest.Mock; const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(() => false); getBooleanInputSpy.mockImplementation(input => false);
const pythonDir: string = path.join(toolDir, 'Python', '3.0.0', 'x64'); const pythonDir: string = path.join(toolDir, 'Python', '3.0.0', 'x64');
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
@@ -135,13 +79,16 @@ describe('Finder tests', () => {
}); });
it('Finds stable Python version if it is not installed, but exists in the manifest', async () => { it('Finds stable Python version if it is not installed, but exists in the manifest', async () => {
const findSpy = tc.getManifestFromRepo as jest.Mock; const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => manifestData); findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const getBooleanInputSpy = core.getBooleanInput as jest.Mock; const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(() => false); getBooleanInputSpy.mockImplementation(input => false);
const installSpy = installer.installCpythonFromRelease as jest.Mock; const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => { installSpy.mockImplementation(async () => {
const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', 'x64'); const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', 'x64');
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
@@ -166,13 +113,16 @@ describe('Finder tests', () => {
}); });
it('Finds pre-release Python version in the manifest', async () => { it('Finds pre-release Python version in the manifest', async () => {
const findSpy = tc.getManifestFromRepo as jest.Mock; const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => manifestData); findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const getBooleanInputSpy = core.getBooleanInput as jest.Mock; const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(() => false); getBooleanInputSpy.mockImplementation(input => false);
const installSpy = installer.installCpythonFromRelease as jest.Mock; const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => { installSpy.mockImplementation(async () => {
const pythonDir: string = path.join( const pythonDir: string = path.join(
toolDir, toolDir,
@@ -200,34 +150,40 @@ describe('Finder tests', () => {
}); });
it('Check-latest true, finds the latest version in the manifest', async () => { it('Check-latest true, finds the latest version in the manifest', async () => {
const findSpy = tc.getManifestFromRepo as jest.Mock; const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => manifestData); findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const getBooleanInputSpy = core.getBooleanInput as jest.Mock; const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(() => true); getBooleanInputSpy.mockImplementation(input => true);
const cnSpy = jest.spyOn(process.stdout, 'write'); const cnSpy: jest.SpyInstance = jest.spyOn(process.stdout, 'write');
cnSpy.mockImplementation(() => true); cnSpy.mockImplementation(line => {
// uncomment to debug
// process.stderr.write('write:' + line + '\n');
});
const addPathSpy = core.addPath as jest.Mock; const addPathSpy: jest.SpyInstance = jest.spyOn(core, 'addPath');
addPathSpy.mockImplementation(() => null); addPathSpy.mockImplementation(() => null);
const infoSpy = core.info as jest.Mock; const infoSpy: jest.SpyInstance = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {}); infoSpy.mockImplementation(() => {});
const debugSpy = core.debug as jest.Mock; const debugSpy: jest.SpyInstance = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => {}); debugSpy.mockImplementation(() => {});
const pythonDir: string = path.join(toolDir, 'Python', '1.2.2', 'x64'); const pythonDir: string = path.join(toolDir, 'Python', '1.2.2', 'x64');
const expPath: string = path.join(toolDir, 'Python', '1.2.3', 'x64'); const expPath: string = path.join(toolDir, 'Python', '1.2.3', 'x64');
const installSpy = installer.installCpythonFromRelease as jest.Mock; const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => { installSpy.mockImplementation(async () => {
await io.mkdirP(expPath); await io.mkdirP(expPath);
fs.writeFileSync(`${expPath}.complete`, 'hello'); fs.writeFileSync(`${expPath}.complete`, 'hello');
}); });
const tcFindSpy = tc.find as jest.Mock; const tcFindSpy: jest.SpyInstance = jest.spyOn(tc, 'find');
tcFindSpy tcFindSpy
.mockImplementationOnce(() => '') .mockImplementationOnce(() => '')
.mockImplementationOnce(() => expPath); .mockImplementationOnce(() => expPath);
@@ -268,10 +224,13 @@ describe('Finder tests', () => {
}); });
it('Finds stable Python version if it is not installed, but exists in the manifest, skipping newer pre-release', async () => { it('Finds stable Python version if it is not installed, but exists in the manifest, skipping newer pre-release', async () => {
const findSpy = tc.getManifestFromRepo as jest.Mock; const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => manifestData); findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const installSpy = installer.installCpythonFromRelease as jest.Mock; const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => { installSpy.mockImplementation(async () => {
const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', 'x64'); const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', 'x64');
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
@@ -287,10 +246,13 @@ describe('Finder tests', () => {
}); });
it('Finds Python version if it is not installed, but exists in the manifest, pre-release fallback', async () => { it('Finds Python version if it is not installed, but exists in the manifest, pre-release fallback', async () => {
const findSpy = tc.getManifestFromRepo as jest.Mock; const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => manifestData); findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const installSpy = installer.installCpythonFromRelease as jest.Mock; const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => { installSpy.mockImplementation(async () => {
const pythonDir: string = path.join( const pythonDir: string = path.join(
toolDir, toolDir,
+67 -125
View File
@@ -1,96 +1,44 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {fileURLToPath} from 'url';
import fs from 'fs'; 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 path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url)); import * as installer from '../src/install-graalpy';
import {
// Mock @actions modules
jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
jest.unstable_mockModule('@actions/tool-cache', () => ({
find: jest.fn(),
findAllVersions: jest.fn(),
downloadTool: jest.fn(),
extractZip: jest.fn(),
extractTar: jest.fn(),
extract7z: jest.fn(),
extractXar: jest.fn(),
cacheDir: jest.fn(),
cacheFile: jest.fn(),
getManifestFromRepo: jest.fn(),
findFromManifest: jest.fn(),
evaluateVersions: jest.fn()
}));
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
// Dynamic imports after mocking
const core = await import('@actions/core');
const tc = await import('@actions/tool-cache');
const exec = await import('@actions/exec');
// Non-mocked imports
import {HttpClient} from '@actions/http-client';
import type * as ifm from '@actions/http-client/lib/interfaces';
const installer = await import('../src/install-graalpy.js');
const utils = await import('../src/utils.js');
import type {
IGraalPyManifestRelease, IGraalPyManifestRelease,
IGraalPyManifestAsset IGraalPyManifestAsset,
} from '../src/utils.js'; IS_WINDOWS
import manifestData from './data/graalpy.json' with {type: 'json'}; } from '../src/utils';
const IS_WINDOWS = utils.IS_WINDOWS; import manifestData from './data/graalpy.json';
const architecture = 'x64'; const architecture = 'x64';
const toolDir = path.join(__dirname, 'runner', 'tools'); const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp'); const tempDir = path.join(__dirname, 'runner', 'temp');
/* GraalPy doesn't have a windows release yet */
const describeSkipOnWindows = IS_WINDOWS ? describe.skip : describe;
describe('graalpyVersionToSemantic', () => { describe('graalpyVersionToSemantic', () => {
it.each([ it.each([
['graalpy-24.1.0-ea.09', '24.1.0-ea.9'], ['23.0.0a1', '23.0.0a1'],
['graal-23.0.0', '23.0.0'], ['23.0.0', '23.0.0'],
['vm-23.0.x', '23.0.x'], ['23.0.x', '23.0.x'],
['graal-23.x', '23.x'] ['23.x', '23.x']
])('%s -> %s', (input, expected) => { ])('%s -> %s', (input, expected) => {
expect(installer.graalPyTagToVersion(input)).toEqual(expected); expect(installer.graalPyTagToVersion(input)).toEqual(expected);
}); });
}); });
describe('findRelease', () => { describeSkipOnWindows('findRelease', () => {
const result = JSON.stringify(manifestData); const result = JSON.stringify(manifestData);
const releases = JSON.parse(result) as IGraalPyManifestRelease[]; const releases = JSON.parse(result) as IGraalPyManifestRelease[];
const extension = IS_WINDOWS ? 'zip' : 'tar.gz'; const extension = 'tar.gz';
const arch = installer.toGraalPyArchitecture(architecture); const arch = installer.toGraalPyArchitecture(architecture);
const platform = installer.toGraalPyPlatform(process.platform); const platform = installer.toGraalPyPlatform(process.platform);
const extensionName = `${platform}-${arch}.${extension}`; const extensionName = `${platform}-${arch}.${extension}`;
@@ -99,22 +47,22 @@ describe('findRelease', () => {
browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.0.0/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 = { const filesRC1: IGraalPyManifestAsset = {
name: `graalpy-24.1.0-ea.09-${extensionName}`, name: `graalpython-23.1.0a1-${extensionName}`,
browser_download_url: `https://github.com/graalvm/graal-languages-ea-builds/releases/download/graalpy-24.1.0-ea.09/graalpy-24.1.0-ea.09-${extensionName}` browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.1.0a1/graalpython-23.1.0a1-${extensionName}`
}; };
let warningSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let infoSpy: jest.Mock; let infoSpy: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {}); infoSpy.mockImplementation(() => {});
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
}); });
@@ -136,15 +84,15 @@ describe('findRelease', () => {
}); });
it('Preview version of GraalPy is found', () => { it('Preview version of GraalPy is found', () => {
const graalpyVersion = installer.graalPyTagToVersion('vm-24.1.0-ea.09'); const graalpyVersion = installer.graalPyTagToVersion('vm-23.1.0a1');
expect( expect(
installer.findRelease(releases, graalpyVersion, architecture, false) installer.findRelease(releases, graalpyVersion, architecture, false)
).toMatchObject({ ).toMatchObject({
foundAsset: { foundAsset: {
name: `graalpy-24.1.0-ea.09-${extensionName}`, name: `graalpython-23.1.0a1-${extensionName}`,
browser_download_url: `https://github.com/graalvm/graal-languages-ea-builds/releases/download/graalpy-24.1.0-ea.09/graalpy-24.1.0-ea.09-${extensionName}` browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.1.0a1/graalpython-23.1.0a1-${extensionName}`
}, },
resolvedGraalPyVersion: '24.1.0-ea.9' resolvedGraalPyVersion: '23.1.0-a.1'
}); });
}); });
@@ -159,7 +107,7 @@ describe('findRelease', () => {
}); });
it('GraalPy version matches semver (pre-release)', () => { it('GraalPy version matches semver (pre-release)', () => {
const graalpyVersion = '24.1.x'; const graalpyVersion = '23.1.x';
expect( expect(
installer.findRelease(releases, graalpyVersion, architecture, false) installer.findRelease(releases, graalpyVersion, architecture, false)
).toBeNull(); ).toBeNull();
@@ -167,60 +115,54 @@ describe('findRelease', () => {
installer.findRelease(releases, graalpyVersion, architecture, true) installer.findRelease(releases, graalpyVersion, architecture, true)
).toMatchObject({ ).toMatchObject({
foundAsset: filesRC1, foundAsset: filesRC1,
resolvedGraalPyVersion: '24.1.0-ea.9' resolvedGraalPyVersion: '23.1.0-a.1'
}); });
}); });
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
}); });
describe('installGraalPy', () => { describeSkipOnWindows('installGraalPy', () => {
let tcFind: jest.Mock; let tcFind: jest.SpyInstance;
let infoSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let warningSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let infoSpy: jest.SpyInstance;
let spyExtractZip: jest.Mock; let spyExtractZip: jest.SpyInstance;
let spyExtractTar: jest.Mock; let spyExtractTar: jest.SpyInstance;
let spyFsReadDir: jest.SpiedFunction<typeof fs.readdirSync>; let spyFsReadDir: jest.SpyInstance;
let spyFsWriteFile: jest.SpiedFunction<typeof fs.writeFileSync>; let spyFsWriteFile: jest.SpyInstance;
let spyHttpClient: jest.SpiedFunction<typeof HttpClient.prototype.getJson>; let spyHttpClient: jest.SpyInstance;
let spyExistsSync: jest.SpiedFunction<typeof fs.existsSync>; let spyExistsSync: jest.SpyInstance;
let spyExec: jest.Mock; let spyExec: jest.SpyInstance;
let spySymlinkSync: jest.SpiedFunction<typeof fs.symlinkSync>; let spySymlinkSync: jest.SpyInstance;
let spyDownloadTool: jest.Mock; let spyDownloadTool: jest.SpyInstance;
let spyCacheDir: jest.Mock; let spyCacheDir: jest.SpyInstance;
let spyChmodSync: jest.SpiedFunction<typeof fs.chmodSync>; let spyChmodSync: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
tcFind = tc.find as jest.Mock; tcFind = jest.spyOn(tc, 'find');
tcFind.mockImplementation(() => tcFind.mockImplementation(() =>
path.join('GraalPy', '3.6.12', architecture) path.join('GraalPy', '3.6.12', architecture)
); );
spyDownloadTool = tc.downloadTool as jest.Mock; spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'GraalPy')); spyDownloadTool.mockImplementation(() => path.join(tempDir, 'GraalPy'));
spyExtractZip = tc.extractZip as jest.Mock; spyExtractZip = jest.spyOn(tc, 'extractZip');
spyExtractZip.mockImplementation(() => tempDir); spyExtractZip.mockImplementation(() => tempDir);
spyExtractTar = tc.extractTar as jest.Mock; spyExtractTar = jest.spyOn(tc, 'extractTar');
spyExtractTar.mockImplementation(() => tempDir); spyExtractTar.mockImplementation(() => tempDir);
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {}); infoSpy.mockImplementation(() => {});
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
spyFsReadDir = jest.spyOn(fs, 'readdirSync'); spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation(() => ['GraalPyTest'] as any); spyFsReadDir.mockImplementation(() => ['GraalPyTest']);
spyFsWriteFile = jest.spyOn(fs, 'writeFileSync'); spyFsWriteFile = jest.spyOn(fs, 'writeFileSync');
spyFsWriteFile.mockImplementation(() => undefined); spyFsWriteFile.mockImplementation(() => undefined);
@@ -237,7 +179,7 @@ describe('installGraalPy', () => {
} }
); );
spyExec = exec.exec as jest.Mock; spyExec = jest.spyOn(exec, 'exec');
spyExec.mockImplementation(() => undefined); spyExec.mockImplementation(() => undefined);
spySymlinkSync = jest.spyOn(fs, 'symlinkSync'); spySymlinkSync = jest.spyOn(fs, 'symlinkSync');
@@ -266,7 +208,7 @@ describe('installGraalPy', () => {
}); });
it('found and install GraalPy', async () => { it('found and install GraalPy', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '21.3.0', architecture) path.join(toolDir, 'GraalPy', '21.3.0', architecture)
); );
@@ -288,22 +230,22 @@ describe('installGraalPy', () => {
}); });
it('found and install GraalPy, pre-release fallback', async () => { it('found and install GraalPy, pre-release fallback', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '24.1.0', architecture) path.join(toolDir, 'GraalPy', '23.1.0', architecture)
); );
spyChmodSync = jest.spyOn(fs, 'chmodSync'); spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
installer.installGraalPy('24.1.x', architecture, false, undefined) installer.installGraalPy('23.1.x', architecture, false, undefined)
).rejects.toThrow(); ).rejects.toThrow();
await expect( await expect(
installer.installGraalPy('24.1.x', architecture, true, undefined) installer.installGraalPy('23.1.x', architecture, true, undefined)
).resolves.toEqual({ ).resolves.toEqual({
installDir: path.join(toolDir, 'GraalPy', '24.1.0', architecture), installDir: path.join(toolDir, 'GraalPy', '23.1.0', architecture),
resolvedGraalPyVersion: '24.1.0-ea.9' resolvedGraalPyVersion: '23.1.0-a.1'
}); });
expect(spyHttpClient).toHaveBeenCalled(); expect(spyHttpClient).toHaveBeenCalled();
+47 -103
View File
@@ -1,72 +1,20 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {fileURLToPath} from 'url';
import fs from 'fs'; 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 path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url)); import * as installer from '../src/install-pypy';
import {
IPyPyManifestRelease,
IPyPyManifestAsset,
IS_WINDOWS
} from '../src/utils';
// Mock @actions modules import manifestData from './data/pypy.json';
jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
jest.unstable_mockModule('@actions/tool-cache', () => ({
find: jest.fn(),
findAllVersions: jest.fn(),
downloadTool: jest.fn(),
extractZip: jest.fn(),
extractTar: jest.fn(),
extract7z: jest.fn(),
extractXar: jest.fn(),
cacheDir: jest.fn(),
cacheFile: jest.fn(),
getManifestFromRepo: jest.fn(),
findFromManifest: jest.fn(),
evaluateVersions: jest.fn()
}));
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
// Dynamic imports after mocking
const core = await import('@actions/core');
const tc = await import('@actions/tool-cache');
const exec = await import('@actions/exec');
// Non-mocked imports
import {HttpClient} from '@actions/http-client';
import type * as ifm from '@actions/http-client/lib/interfaces';
const installer = await import('../src/install-pypy.js');
const utils = await import('../src/utils.js');
import type {IPyPyManifestRelease, IPyPyManifestAsset} from '../src/utils.js';
import manifestData from './data/pypy.json' with {type: 'json'};
const IS_WINDOWS = utils.IS_WINDOWS;
let architecture: string; let architecture: string;
if (IS_WINDOWS) { if (IS_WINDOWS) {
@@ -110,18 +58,19 @@ describe('findRelease', () => {
download_url: `https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-${extensionName}` download_url: `https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-${extensionName}`
}; };
let infoSpy: jest.Mock; let getBooleanInputSpy: jest.SpyInstance;
let warningSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {}); infoSpy.mockImplementation(() => {});
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
}); });
@@ -266,55 +215,50 @@ describe('findRelease', () => {
resolvedPyPyVersion: pypyVersion resolvedPyPyVersion: pypyVersion
}); });
}); });
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
}); });
describe('installPyPy', () => { describe('installPyPy', () => {
let tcFind: jest.Mock; let tcFind: jest.SpyInstance;
let infoSpy: jest.Mock; let getBooleanInputSpy: jest.SpyInstance;
let warningSpy: jest.Mock; let warningSpy: jest.SpyInstance;
let debugSpy: jest.Mock; let debugSpy: jest.SpyInstance;
let spyExtractZip: jest.Mock; let infoSpy: jest.SpyInstance;
let spyExtractTar: jest.Mock; let spyExtractZip: jest.SpyInstance;
let spyFsReadDir: jest.SpiedFunction<typeof fs.readdirSync>; let spyExtractTar: jest.SpyInstance;
let spyFsWriteFile: jest.SpiedFunction<typeof fs.writeFileSync>; let spyFsReadDir: jest.SpyInstance;
let spyHttpClient: jest.SpiedFunction<typeof HttpClient.prototype.getJson>; let spyFsWriteFile: jest.SpyInstance;
let spyExistsSync: jest.SpiedFunction<typeof fs.existsSync>; let spyHttpClient: jest.SpyInstance;
let spyExec: jest.Mock; let spyExistsSync: jest.SpyInstance;
let spySymlinkSync: jest.SpiedFunction<typeof fs.symlinkSync>; let spyExec: jest.SpyInstance;
let spyDownloadTool: jest.Mock; let spySymlinkSync: jest.SpyInstance;
let spyCacheDir: jest.Mock; let spyDownloadTool: jest.SpyInstance;
let spyChmodSync: jest.SpiedFunction<typeof fs.chmodSync>; let spyCacheDir: jest.SpyInstance;
let spyChmodSync: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
tcFind = tc.find as jest.Mock; tcFind = jest.spyOn(tc, 'find');
tcFind.mockImplementation(() => path.join('PyPy', '3.6.12', architecture)); tcFind.mockImplementation(() => path.join('PyPy', '3.6.12', architecture));
spyDownloadTool = tc.downloadTool as jest.Mock; spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'PyPy')); spyDownloadTool.mockImplementation(() => path.join(tempDir, 'PyPy'));
spyExtractZip = tc.extractZip as jest.Mock; spyExtractZip = jest.spyOn(tc, 'extractZip');
spyExtractZip.mockImplementation(() => tempDir); spyExtractZip.mockImplementation(() => tempDir);
spyExtractTar = tc.extractTar as jest.Mock; spyExtractTar = jest.spyOn(tc, 'extractTar');
spyExtractTar.mockImplementation(() => tempDir); spyExtractTar.mockImplementation(() => tempDir);
infoSpy = core.info as jest.Mock; infoSpy = jest.spyOn(core, 'info');
infoSpy.mockImplementation(() => {}); infoSpy.mockImplementation(() => {});
warningSpy = core.warning as jest.Mock; warningSpy = jest.spyOn(core, 'warning');
warningSpy.mockImplementation(() => null); warningSpy.mockImplementation(() => null);
debugSpy = core.debug as jest.Mock; debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(() => null); debugSpy.mockImplementation(() => null);
spyFsReadDir = jest.spyOn(fs, 'readdirSync'); spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation(() => ['PyPyTest'] as any); spyFsReadDir.mockImplementation(() => ['PyPyTest']);
spyFsWriteFile = jest.spyOn(fs, 'writeFileSync'); spyFsWriteFile = jest.spyOn(fs, 'writeFileSync');
spyFsWriteFile.mockImplementation(() => undefined); spyFsWriteFile.mockImplementation(() => undefined);
@@ -331,7 +275,7 @@ describe('installPyPy', () => {
} }
); );
spyExec = exec.exec as jest.Mock; spyExec = jest.spyOn(exec, 'exec');
spyExec.mockImplementation(() => undefined); spyExec.mockImplementation(() => undefined);
spySymlinkSync = jest.spyOn(fs, 'symlinkSync'); spySymlinkSync = jest.spyOn(fs, 'symlinkSync');
@@ -360,7 +304,7 @@ describe('installPyPy', () => {
}); });
it('found and install PyPy', async () => { it('found and install PyPy', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.6.12', architecture) path.join(toolDir, 'PyPy', '3.6.12', architecture)
); );
@@ -384,7 +328,7 @@ describe('installPyPy', () => {
}); });
it('found and install PyPy, pre-release fallback', async () => { it('found and install PyPy, pre-release fallback', async () => {
spyCacheDir = tc.cacheDir as jest.Mock; spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.6.12', architecture) path.join(toolDir, 'PyPy', '3.6.12', architecture)
); );

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