Compare commits

..

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

120 changed files with 43653 additions and 102381 deletions

View File

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

View File

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

2
.github/CODEOWNERS vendored
View File

@ -1 +1 @@
* @actions/setup-actions-team
* @actions/actions-service

View File

@ -1 +1 @@
blank_issues_enabled: false
blank_issues_enabled: false

View File

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

View File

@ -1,17 +0,0 @@
name: Basic validation
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
call-basic-validation:
name: Basic validation
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
with:
node-version: '20.x'

View File

@ -1,3 +1,8 @@
# `dist/index.js` is a special file in Actions.
# When you reference an action with `uses:` in a workflow,
# `index.js` is the code that will run.
# For our project, we generate this file through a build process from other source files.
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
name: Check dist/
on:
@ -12,8 +17,36 @@ on:
workflow_dispatch:
jobs:
call-check-dist:
name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
with:
node-version: '20.x'
check-dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Rebuild the dist/ directory
run: npm run build
- name: Compare the expected and actual dist/ directories
run: |
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
git diff
exit 1
fi
id: diff
# If index.js was different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@v3
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:
name: dist
path: dist/

View File

@ -1,13 +1,47 @@
name: CodeQL analysis
name: "Code scanning - action"
on:
push:
branches: ['main']
branches: [ 'main' ]
pull_request:
schedule:
- cron: '0 3 * * 0'
- cron: '25 3 * * 5'
jobs:
call-codeQL-analysis:
name: CodeQL analysis
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
CodeQL-Build:
strategy:
fail-fast: false
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

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

View File

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

View File

@ -1,95 +0,0 @@
name: e2e tests
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
jobs:
test-setup-python:
name: Test setup-python
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system:
[
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-latest,
ubuntu-24.04-arm,
macos-latest,
macos-13
]
steps:
- name: Checkout
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.9.13
uses: ./
with:
python-version: 3.10.11
- name: Verify 3.10.11
run: python __tests__/verify-python.py 3.10.11
- name: Run with setup-python 3.11.9
uses: ./
with:
python-version: 3.11.9
- name: Verify 3.11.9
run: python __tests__/verify-python.py 3.11.9
- name: Run with setup-python 3.12.7
uses: ./
with:
python-version: 3.12.7
- name: Verify 3.12.7
run: python __tests__/verify-python.py 3.12.7
- name: Run with setup-python 3.13.0
uses: ./
with:
python-version: 3.13.0
- name: Verify 3.13.0
run: python __tests__/verify-python.py 3.13.0
- name: Run with setup-python 3.13
id: cp313
uses: ./
with:
python-version: '3.13'
- name: Verify 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
run: |
curl -L https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json | jq empty
shell: bash

View File

@ -9,6 +9,21 @@ on:
- main
jobs:
call-licensed:
name: Licensed
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
test:
runs-on: ubuntu-latest
name: Check licenses
steps:
- uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm
- run: npm ci
- name: Install licensed
run: |
cd $RUNNER_TEMP
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.4.4/licensed-3.4.4-linux-x64.tar.gz
sudo tar -xzf licensed.tar.gz
sudo mv licensed /usr/local/bin/licensed
- run: licensed status

View File

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

View File

@ -1,5 +1,4 @@
name: Release new action version
on:
release:
types: [released]
@ -21,8 +20,8 @@ jobs:
name: releaseNewActionVersion
runs-on: ubuntu-latest
steps:
- name: Update the ${{ env.TAG_NAME }} tag
uses: actions/publish-action@v0.3.0
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
- name: Update the ${{ env.TAG_NAME }} tag
uses: actions/publish-action@v0.2.0
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

View File

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

View File

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

View File

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

View File

@ -1,5 +1,4 @@
name: Validate Python e2e
on:
push:
branches:
@ -20,43 +19,34 @@ jobs:
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v3
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} version file
@ -64,343 +54,99 @@ jobs:
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v3
- name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version
- name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: .python-version
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: '.python-version'
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-file-without-parameter:
name: Setup ${{ matrix.python }} ${{ matrix.os }} version file without parameter
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: echo ${{ matrix.python }} > .python-version
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-standard-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} standard pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, '==3.12.3', 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: |
echo '[project]
requires-python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}".replace("==", "") -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-poetry-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} poetry pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [3.9.13, 3.10.11, 3.11.9, 3.12.3, 3.13.2]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-version-file ${{ matrix.python }}
run: |
echo '[tool.poetry.dependencies]
python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-from-tool-versions-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} .tool-versions file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: [pypy3.11-7.3.18, graalpy-24.1.2, 3.13.2, 3.14-dev]
exclude:
- os: windows-latest
python: graalpy-24.1.2
steps:
- name: Checkout
uses: actions/checkout@v4
- name: build-tool-versions-file ${{ matrix.python }}
run: |
echo "python ${{ matrix.python }}" > .tool-versions
- name: setup-python using .tool-versions ${{ matrix.python }}
id: setup-python-tool-versions
uses: ./
with:
python-version-file: .tool-versions
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-pre-release-version-from-manifest:
name: Setup 3.14.0-alpha.6 ${{ matrix.os }}
name: Setup 3.9.0-beta.4 ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v3
- name: setup-python 3.14.0-alpha.6
id: setup-python
uses: ./
with:
python-version: '3.14.0-alpha.6'
- name: setup-python 3.9.0-beta.4
id: setup-python
uses: ./
with:
python-version: '3.9.0-beta.4'
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- 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 3.14.0a6" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is 3.14.0a6"
exit 1
}
$pythonVersion
shell: pwsh
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python 3.9.0b4" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is 3.9.0b4"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-dev-version:
name: Setup 3.14-dev ${{ matrix.os }}
name: Setup 3.9-dev ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v3
- name: setup-python 3.14-dev
id: setup-python
uses: ./
with:
python-version: '3.14-dev'
- name: setup-python 3.9-dev
id: setup-python
uses: ./
with:
python-version: '3.9-dev'
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash
- name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.9.') }}
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-prerelease-version:
name: Setup 3.14 ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: setup-python 3.14
id: setup-python
uses: ./
with:
python-version: '3.14'
allow-prereleases: true
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.14.') }}
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-noenv:
name: Setup ${{ matrix.python }} ${{ matrix.os }} (noenv)
@ -408,52 +154,34 @@ jobs:
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
macos-13,
ubuntu-latest,
ubuntu-24.04-arm
]
python: ['3.9', '3.10', '3.11', '3.12', '3.13']
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: ["3.7", "3.8", "3.9", "3.10"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v3
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
update-environment: false
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
update-environment: false
- name: Python version
run: ${{ steps.setup-python.outputs.python-path }} --version
- name: Python version
run: ${{ steps.setup-python.outputs.python-path }} --version
- name: Run simple code
run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))'
- name: Run simple code
run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))'
check-latest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup Python and check latest
uses: ./
with:
@ -462,46 +190,9 @@ jobs:
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("$pythonVersion" -NotMatch "${{ matrix.python-version }}"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python-version }}"
if ("$pythonVersion" -NotMatch "${{ matrix.python }}"){
Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
exit 1
}
$pythonVersion
shell: pwsh
setup-python-multiple-python-versions:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
windows-latest,
ubuntu-22.04,
ubuntu-22.04-arm,
ubuntu-24.04-arm,
ubuntu-latest,
macos-13
]
steps:
- uses: actions/checkout@v4
- name: Setup Python and check latest
uses: ./
with:
python-version: |
3.9
3.10
3.11
3.12
3.13
check-latest: true
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("$pythonVersion" -NotMatch "3.13"){
Write-Host "The current version is $pythonVersion; expected version is 3.13"
exit 1
}
$pythonVersion
shell: pwsh
shell: pwsh

View File

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

101
.github/workflows/workflow.yml vendored Normal file
View File

@ -0,0 +1,101 @@
name: Main workflow
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
run:
name: Run
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: [ubuntu-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm
- name: npm ci
run: npm ci
- name: Lint
run: npm run format-check
- name: npm test
run: npm test
- name: Run with setup-python 2.7
uses: ./
with:
python-version: 2.7
- name: Verify 2.7
run: python __tests__/verify-python.py 2.7
- name: Run with setup-python 3.5
uses: ./
with:
python-version: 3.5
- name: Verify 3.5
run: python __tests__/verify-python.py 3.5
- name: Run with setup-python 3.6
uses: ./
with:
python-version: 3.6
- name: Verify 3.6
run: python __tests__/verify-python.py 3.6
- name: Run with setup-python 3.7
uses: ./
with:
python-version: 3.7
- name: Verify 3.7
run: python __tests__/verify-python.py 3.7
- name: Run with setup-python 3.8
uses: ./
with:
python-version: 3.8
- name: Verify 3.8
run: python __tests__/verify-python.py 3.8
- name: Run with setup-python 3.7.5
uses: ./
with:
python-version: 3.7.5
- name: Verify 3.7.5
run: python __tests__/verify-python.py 3.7.5
- name: Run with setup-python 3.6.7
uses: ./
with:
python-version: 3.6.7
- name: Verify 3.6.7
run: python __tests__/verify-python.py 3.6.7
- name: Run with setup-python 3.8.1
uses: ./
with:
python-version: 3.8.1
- name: Verify 3.8.1
run: python __tests__/verify-python.py 3.8.1
- name: Run with setup-python 3.10
id: cp310
uses: ./
with:
python-version: "3.10"
- name: Verify 3.10
run: python __tests__/verify-python.py 3.10
- name: Run python-path sample 3.10
run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

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

11
.prettierrc.json Normal file
View File

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

View File

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

View File

@ -1,20 +1,19 @@
import * as path from 'path';
import * as core from '@actions/core';
import * as cache from '@actions/cache';
import * as exec from '@actions/exec';
import * as io from '@actions/io';
import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
import {State} from '../src/cache-distributions/cache-distributor';
import * as utils from './../src/utils';
describe('restore-cache', () => {
const pipFileLockHash =
'f8428d7cf00ea53a5c3702f0a9cb3cc467f76cd86a34723009350c4e4b32751a';
'a3bdcc71289e4979ca9e051810d81999cc99823109faf6912e17ff14c8e621a6';
const requirementsHash =
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
const requirementsLinuxHash =
'2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c';
const poetryLockHash =
'f24ea1ad73968e6c8d80c16a093ade72d9332c433aeef979a0dd943e6a99b2ab';
'571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836';
const poetryConfigOutput = `
cache-dir = "/Users/patrick/Library/Caches/pypoetry"
experimental.new-installer = false
@ -28,9 +27,10 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
let infoSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance;
let saveStateSpy: jest.SpyInstance;
let saveSatetSpy: jest.SpyInstance;
let getStateSpy: jest.SpyInstance;
let setOutputSpy: jest.SpyInstance;
let getLinuxOSReleaseInfoSpy: jest.SpyInstance;
// cache spy
let restoreCacheSpy: jest.SpyInstance;
@ -53,8 +53,8 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(input => undefined);
saveStateSpy = jest.spyOn(core, 'saveState');
saveStateSpy.mockImplementation(input => undefined);
saveSatetSpy = jest.spyOn(core, 'saveState');
saveSatetSpy.mockImplementation(input => undefined);
getStateSpy = jest.spyOn(core, 'getState');
getStateSpy.mockImplementation(input => undefined);
@ -67,9 +67,6 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
if (input.includes('poetry')) {
return {stdout: poetryConfigOutput, stderr: '', exitCode: 0};
}
if (input.includes('lsb_release')) {
return {stdout: 'Ubuntu\n20.04', stderr: '', exitCode: 0};
}
return {stdout: '', stderr: 'Error occured', exitCode: 2};
});
@ -86,6 +83,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
whichSpy = jest.spyOn(io, 'which');
whichSpy.mockImplementation(() => '/path/to/python');
getLinuxOSReleaseInfoSpy = jest.spyOn(utils, 'getLinuxOSReleaseInfo');
});
describe('Validate provided package manager', () => {
@ -94,126 +92,60 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
async packageManager => {
expect(() =>
getCacheDistributor(packageManager, '3.8.12', undefined)
).toThrow(`Caching for '${packageManager}' is not supported`);
).toThrowError(`Caching for '${packageManager}' is not supported`);
}
);
});
describe('Restore dependencies', () => {
it.each([
[
'pip',
'3.8.12',
'__tests__/data/**/requirements.txt',
requirementsHash,
undefined
],
[
'pip',
'3.8.12',
'__tests__/data/**/requirements-linux.txt',
requirementsLinuxHash,
undefined
],
['pip', '3.8.12', undefined, requirementsHash],
['pip', '3.8.12', '**/requirements-linux.txt', requirementsLinuxHash],
[
'pip',
'3.8.12',
'__tests__/data/requirements-linux.txt',
requirementsLinuxHash,
undefined
requirementsLinuxHash
],
[
'pip',
'3.8.12',
'__tests__/data/requirements.txt',
requirementsHash,
undefined
],
[
'pipenv',
'3.9.1',
'__tests__/data/**/Pipfile.lock',
pipFileLockHash,
undefined
],
[
'pipenv',
'3.9.12',
'__tests__/data/requirements.txt',
requirementsHash,
undefined
],
[
'poetry',
'3.9.1',
'__tests__/data/**/poetry.lock',
poetryLockHash,
[
'/Users/patrick/Library/Caches/pypoetry/virtualenvs',
path.join(__dirname, 'data', 'inner', '.venv'),
path.join(__dirname, 'data', '.venv')
]
]
['pip', '3.8.12', '__tests__/data/requirements.txt', requirementsHash],
['pipenv', '3.9.1', undefined, pipFileLockHash],
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
['poetry', '3.9.1', undefined, poetryLockHash]
])(
'restored dependencies for %s by primaryKey',
async (
packageManager,
pythonVersion,
dependencyFile,
fileHash,
cachePaths
) => {
restoreCacheSpy.mockImplementation(
(cachePaths: string[], primaryKey: string, restoreKey?: string) => {
return primaryKey.includes(fileHash) ? primaryKey : '';
}
);
async (packageManager, pythonVersion, dependencyFile, fileHash) => {
const cacheDistributor = getCacheDistributor(
packageManager,
pythonVersion,
dependencyFile
);
await cacheDistributor.restoreCache();
if (cachePaths !== undefined) {
expect(saveStateSpy).toHaveBeenCalledWith(
State.CACHE_PATHS,
cachePaths
if (process.platform === 'linux') {
getLinuxOSReleaseInfoSpy.mockImplementation(() =>
Promise.resolve('Ubuntu-20.4')
);
}
const restoredKeys = restoreCacheSpy.mock.results.map(
result => result.value
);
await cacheDistributor.restoreCache();
restoredKeys.forEach(restoredKey => {
if (restoredKey) {
if (process.platform === 'linux' && packageManager === 'pip') {
expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${process.arch}-20.04-Ubuntu-python-${pythonVersion}-${packageManager}-${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 {
expect(infoSpy).toHaveBeenCalledWith(
`${packageManager} cache is not found`
);
}
});
if (process.platform === 'linux' && packageManager === 'pip') {
expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-Ubuntu-20.4-python-${pythonVersion}-${packageManager}-${fileHash}`
);
} else {
expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-${fileHash}`
);
}
},
30000
);
it.each([['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']])(
it.each([
['pip', '3.8.12', 'requirements-linux.txt', 'requirements-linux.txt'],
['pip', '3.8.12', 'requirements.txt', 'requirements.txt'],
['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']
])(
'Should throw an error because dependency file is not found',
async (
packageManager,
@ -226,58 +158,19 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
pythonVersion,
dependencyFile
);
await expect(cacheDistributor.restoreCache()).rejects.toThrow(
await expect(cacheDistributor.restoreCache()).rejects.toThrowError(
`No file in ${process.cwd()} matched to [${cacheDependencyPath
.split('\n')
.join(',')}], make sure you have checked out the target repository`
);
}
);
it.each([
['pip', '3.8.12', 'requirements-linux.txt'],
['pip', '3.8.12', 'requirements.txt']
])(
'Shouldn`t throw an error as there is a default file `pyproject.toml` to use when requirements.txt is not specified',
async (packageManager, pythonVersion, dependencyFile) => {
const cacheDistributor = getCacheDistributor(
packageManager,
pythonVersion,
dependencyFile
);
await expect(cacheDistributor.restoreCache()).resolves.not.toThrow();
}
);
it.each([
['pip', '3.8.12', 'requirements-linux.txt'],
['pip', '3.8.12', 'requirements.txt']
])(
'Should throw an error as there is no default file `pyproject.toml` to use when requirements.txt is not specified',
async (packageManager, pythonVersion, dependencyFile) => {
const cacheDistributor = getCacheDistributor(
packageManager,
pythonVersion,
dependencyFile
) as any; // Widening PipCache | PipenvCache | PoetryCache type to any allow us to change private property on the cacheDistributor to test value: "**/pyprojecttest.toml"
cacheDistributor.cacheDependencyBackupPath = '**/pyprojecttest.toml';
await expect(cacheDistributor.restoreCache()).rejects.toThrow();
}
);
});
describe('Dependencies changed', () => {
it.each([
['pip', '3.8.12', '__tests__/data/**/requirements.txt', pipFileLockHash],
[
'pip',
'3.8.12',
'__tests__/data/**/requirements-linux.txt',
pipFileLockHash
],
['pip', '3.8.12', undefined, pipFileLockHash],
['pip', '3.8.12', '**/requirements-linux.txt', pipFileLockHash],
[
'pip',
'3.8.12',
@ -285,9 +178,9 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
pipFileLockHash
],
['pip', '3.8.12', '__tests__/data/requirements.txt', pipFileLockHash],
['pipenv', '3.9.1', '__tests__/data/**/Pipfile.lock', requirementsHash],
['pipenv', '3.9.1', undefined, requirementsHash],
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
['poetry', '3.9.1', '__tests__/data/**/poetry.lock', requirementsHash]
['poetry', '3.9.1', undefined, requirementsHash]
])(
'restored dependencies for %s by primaryKey',
async (packageManager, pythonVersion, dependencyFile, fileHash) => {

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
../poetry.lock

View File

@ -1 +0,0 @@
../pyproject.toml

View File

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

View File

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

View File

@ -5,13 +5,11 @@ description = ""
authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies]
python = ">=3.8,<3.14"
python = "^3.8"
flake8 = "^4.0.1"
pyinstaller = "6.10.0"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
build-backend = "poetry.core.masonry.api"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,24 +11,18 @@ inputs:
description: "Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv, poetry."
required: false
architecture:
description: "The target architecture (x86, x64, arm64) of the Python or PyPy interpreter."
description: "The target architecture (x86, x64) of the Python or PyPy interpreter."
check-latest:
description: "Set this option if you want the action to check for the latest available version that satisfies the version spec."
default: false
token:
description: "The token used to authenticate when fetching Python distributions from https://github.com/actions/python-versions. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting."
default: ${{ github.server_url == 'https://github.com' && github.token || '' }}
description: "Used to pull python distributions from actions/python-versions. Since there's a default, this is typically not supplied by the user."
default: ${{ github.token }}
cache-dependency-path:
description: "Used to specify the path to dependency files. Supports wildcards or a list of file names for caching multiple dependencies."
update-environment:
description: "Set this option if you want the action to update environment variables."
default: true
allow-prereleases:
description: "When 'true', a version range passed to 'python-version' input will match prerelease versions if no GA versions are found. Only 'x.y' version range is supported for CPython."
default: false
freethreaded:
description: "When 'true', use the freethreaded version of Python."
default: false
outputs:
python-version:
description: "The installed Python or PyPy version. Useful when given a version range as input."
@ -37,7 +31,7 @@ outputs:
python-path:
description: "The absolute path to the Python or PyPy executable."
runs:
using: 'node20'
using: 'node16'
main: 'dist/setup/index.js'
post: 'dist/cache-save/index.js'
post-if: success()

51904
dist/cache-save/index.js vendored

File diff suppressed because one or more lines are too long

61221
dist/setup/index.js vendored

File diff suppressed because one or more lines are too long

View File

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

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