Compare commits

...

18 Commits

Author SHA1 Message Date
57ded4d7d5 update @azure/storage-blob (#655) 2023-04-20 14:13:16 +02:00
df6abcc733 update xml2js (#652) 2023-04-19 13:40:45 +02:00
7a4f344e33 Add warning for empty cache paths (#642) 2023-04-06 12:02:34 +02:00
d1244c8404 Remove ubuntu-18.04 from e2e (#641) 2023-04-04 16:18:24 +02:00
3091b37310 Fix glob bug in package.json scripts section (#637) 2023-04-03 12:46:57 +02:00
dfa76f8d0d Update configuration files (#622)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-15 00:32:39 +01:00
03eb867e3d Add error handling for saving and restoring cache (#618) 2023-03-10 12:15:18 +01:00
b41aaf9f0c Merge pull request #621 from akv-platform/reusable-workflow
Turn on automatic update of ESLint and Prettier configuration files
2023-03-10 10:55:42 +01:00
0ffa49cfca Add update-config-files.yml 2023-03-09 11:47:39 +01:00
ec365b4eba Add and configure ESLint and update configuration for Prettier (#617)
* Add ESLint, update Prettier

* Update docs

* Update tests

* Update licenses

* Fix review points
2023-03-09 12:44:56 +02:00
7b9ef6fc5a Add another pip default dependency file for cache hash (#604) 2023-02-20 13:36:57 +01:00
869e769ec8 Trim trailing newlines from resolvedPyPyVersion (#610)
Fixes #609
2023-02-20 11:28:16 +01:00
3faddefb4c Fix GHE documentation link (#602)
Co-authored-by: Fevrin <fevrin@users.noreply.github.com>
2023-02-09 09:31:03 +01:00
181184007f Update workflow badges (#594) 2023-01-31 08:46:32 +02:00
2652534ead feature: fallback to pre-release when no stable version is found (#414)
This allows to specify version like `3.11` or `pypy3.10` in workflows before those versions are released.
This lessen the burden for users of `setup-python` by not having to modify their workflow twice: once when a pre-release is available (e.g. `3.11-dev`) and once when the first stable release is published (e.g. `3.11`)
2023-01-27 16:19:31 -05:00
a6eba85bba Fix small action version typo in docs (#590) 2023-01-18 14:43:44 +01:00
34b4b622e3 Encourage the use of pre-release Python 3.12, not 3.11 (#586) 2023-01-16 10:27:26 +01:00
f60fe39c45 Update release-new-action-version.yml (#584) 2023-01-12 13:52:32 +01:00
57 changed files with 12969 additions and 10407 deletions

6
.eslintignore Normal file
View File

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

50
.eslintrc.js Normal file
View File

@ -0,0 +1,50 @@
// 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-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}]
},
overrides: [
{
files: ['**/*{test,spec}.ts'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'jest/no-standalone-expect': 'off',
'jest/no-conditional-expect': 'off',
'no-console': 'off',
}
}
],
env: {
node: true,
es6: true,
'jest/globals': true
}
};

View File

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

View File

@ -12,4 +12,4 @@ on:
jobs:
call-basic-validation:
name: Basic validation
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main

View File

@ -14,4 +14,4 @@ on:
jobs:
call-check-dist:
name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main

View File

@ -2,12 +2,12 @@ name: CodeQL analysis
on:
push:
branches: [ 'main' ]
branches: ['main']
pull_request:
schedule:
- cron: '0 3 * * 0'
jobs:
call-codeQL-analysis:
name: CodeQL analysis
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
name: CodeQL analysis
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main

View File

@ -128,4 +128,4 @@ jobs:
pipenv install --keep-outdated --python pypy
} else {
pipenv install --keep-outdated --python ${{ matrix.python-version }}
}
}

View File

@ -9,7 +9,7 @@ on:
pull_request:
paths-ignore:
- '**.md'
jobs:
test-setup-python:
name: Test setup-python
@ -18,71 +18,71 @@ jobs:
matrix:
operating-system: [ubuntu-20.04, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3
- 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 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.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.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.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.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.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.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.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
- 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

View File

@ -11,4 +11,4 @@ on:
jobs:
call-licensed:
name: Licensed
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main

View File

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

View File

@ -1,6 +1,6 @@
name: Validate PyPy e2e
on:
on:
push:
branches:
- main
@ -19,24 +19,24 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-latest]
pypy:
- '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'
- '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@v3
- name: setup-python ${{ matrix.pypy }}
id: setup-python
uses: ./
@ -49,7 +49,7 @@ jobs:
- name: PyPy and Python version
run: python --version
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
@ -73,7 +73,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-latest]
pypy: ['pypy2.7', 'pypy3.7', 'pypy3.8', 'pypy3.9-nightly']
steps:
@ -138,8 +138,8 @@ jobs:
uses: ./
with:
python-version: |
pypy-3.7-v7.3.x
pypy3.8
pypy-3.7-v7.3.x
pypy3.8
check-latest: true
- name: PyPy and Python version
run: python --version
@ -166,4 +166,4 @@ jobs:
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

@ -20,34 +20,43 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.15, 3.9.13]
exclude:
- os: ubuntu-22.04
python: 3.5.4
- os: ubuntu-22.04
python: 3.6.7
- os: ubuntu-22.04
python: 3.7.5
- os: windows-latest
python: 3.8.15
steps:
- name: Checkout
uses: actions/checkout@v3
- 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
@ -55,37 +64,46 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.15, 3.9.13]
exclude:
- os: ubuntu-22.04
python: 3.5.4
- os: ubuntu-22.04
python: 3.6.7
- os: ubuntu-22.04
python: 3.7.5
- os: windows-latest
python: 3.8.15
steps:
- name: Checkout
uses: actions/checkout@v3
- 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))'
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-pre-release-version-from-manifest:
name: Setup 3.9.0-beta.4 ${{ matrix.os }}
@ -93,33 +111,33 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
os: [macos-latest, windows-latest, ubuntu-20.04]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3
- name: setup-python 3.9.0-beta.4
id: setup-python
uses: ./
with:
python-version: '3.9.0-beta.4'
- 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.9.0b4" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is 3.9.0b4"
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.9-dev ${{ matrix.os }}
@ -129,25 +147,54 @@ jobs:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3
- name: setup-python 3.9-dev
id: setup-python
uses: ./
with:
python-version: '3.9-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.9.') }}
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))'
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-prerelease-version:
name: Setup 3.12 ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: setup-python 3.12
id: setup-python
uses: ./
with:
python-version: '3.12'
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.12.') }}
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)
@ -155,24 +202,24 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: ["3.7", "3.8", "3.9", "3.10"]
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
python: ['3.7', '3.8', '3.9', '3.10']
steps:
- name: Checkout
uses: actions/checkout@v3
- 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 }}
@ -180,7 +227,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10"]
python-version: ['3.8', '3.9', '3.10']
steps:
- uses: actions/checkout@v3
- name: Setup Python and check latest
@ -210,10 +257,10 @@ jobs:
uses: ./
with:
python-version: |
3.7
3.8
3.9
3.10
3.7
3.8
3.9
3.10
check-latest: true
- name: Validate version
run: |
@ -223,4 +270,4 @@ jobs:
exit 1
}
$pythonVersion
shell: pwsh
shell: pwsh

View File

@ -0,0 +1,11 @@
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

View File

@ -1,6 +1,6 @@
---
name: "@actions/cache"
version: 3.0.4
version: 3.1.4
type: npm
summary: Actions cache lib
homepage: https://github.com/actions/toolkit/tree/main/packages/cache

View File

@ -1,9 +1,9 @@
---
name: "@azure/abort-controller"
version: 1.0.4
version: 1.1.0
type: npm
summary: Microsoft Azure SDK for JavaScript - Aborter
homepage: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/abort-controller/README.md
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller/README.md
license: mit
licenses:
- sources: LICENSE

View File

@ -1,6 +1,6 @@
---
name: "@azure/core-http"
version: 2.2.2
version: 3.0.1
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest

32
.licenses/npm/@azure/core-util.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: "@azure/core-util"
version: 1.3.1
type: npm
summary: Core library for shared utility methods
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-util/
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

View File

@ -1,6 +1,6 @@
---
name: "@azure/ms-rest-js"
version: 2.6.0
version: 2.6.6
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest

View File

@ -1,6 +1,6 @@
---
name: "@azure/storage-blob"
version: 12.8.0
version: 12.14.0
type: npm
summary: Microsoft Azure Storage SDK for JavaScript - Blob
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/

View File

@ -1,6 +1,6 @@
---
name: "@types/node-fetch"
version: 2.5.12
version: 2.6.3
type: npm
summary: TypeScript definitions for node-fetch
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node-fetch

26
.licenses/npm/lru-cache.dep.yml generated Normal file
View File

@ -0,0 +1,26 @@
---
name: lru-cache
version: 6.0.0
type: npm
summary: A cache object that deletes the least-recently-used items.
homepage:
license: isc
licenses:
- sources: LICENSE
text: |
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
notices: []

View File

@ -1,9 +1,9 @@
---
name: semver
version: 7.1.3
version: 7.3.8
type: npm
summary: The semantic version parser used by npm.
homepage: https://github.com/npm/node-semver#readme
homepage:
license: isc
licenses:
- sources: LICENSE

View File

@ -1,23 +0,0 @@
---
name: tough-cookie
version: 4.0.0
type: npm
summary: RFC6265 Cookies and Cookie Jar for node.js
homepage: https://github.com/salesforce/tough-cookie
license: bsd-3-clause
licenses:
- sources: LICENSE
text: |
Copyright (c) 2015, Salesforce.com, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
notices: []

35
.licenses/npm/tslib-2.5.0.dep.yml generated Normal file
View File

@ -0,0 +1,35 @@
---
name: tslib
version: 2.5.0
type: npm
summary: Runtime library for TypeScript helper functions
homepage: https://www.typescriptlang.org/
license: 0bsd
licenses:
- sources: LICENSE.txt
text: |-
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
notices:
- sources: CopyrightNotice.txt
text: "/******************************************************************************\r\nCopyright
(c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute
this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE
SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS
SOFTWARE.\r\n*****************************************************************************
*/"

View File

@ -1,33 +0,0 @@
---
name: universalify
version: 0.1.2
type: npm
summary: Make a callback- or promise-based function support both promises and callbacks.
homepage: https://github.com/RyanZim/universalify#readme
license: mit
licenses:
- sources: LICENSE
text: |
(The MIT License)
Copyright (c) 2017, Ryan Zimmerman <opensrc@ryanzim.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the 'Software'), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: README.md
text: MIT
notices: []

View File

@ -1,6 +1,6 @@
---
name: xml2js
version: 0.4.23
version: 0.5.0
type: npm
summary: Simple XML to JavaScript object converter.
homepage: https://github.com/Leonidas-from-XIV/node-xml2js

26
.licenses/npm/yallist.dep.yml generated Normal file
View File

@ -0,0 +1,26 @@
---
name: yallist
version: 4.0.0
type: npm
summary: Yet Another Linked List
homepage:
license: isc
licenses:
- sources: LICENSE
text: |
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
notices: []

7
.prettierignore Normal file
View File

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

11
.prettierrc.js Normal file
View File

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

View File

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

View File

@ -1,8 +1,9 @@
# setup-python
<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>
[![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)
This action provides the following functionality for GitHub Actions users:
@ -51,7 +52,7 @@ Using `architecture` input it is possible to specify the required Python or PyPy
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` 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` 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.
- For `pip`, the action will cache the global cache directory
- For `pipenv`, the action will cache virtualenv directory
@ -85,6 +86,7 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet
- [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)
## License

View File

@ -5,7 +5,6 @@ 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 =
@ -95,7 +94,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
async packageManager => {
expect(() =>
getCacheDistributor(packageManager, '3.8.12', undefined)
).toThrowError(`Caching for '${packageManager}' is not supported`);
).toThrow(`Caching for '${packageManager}' is not supported`);
}
);
});
@ -164,6 +163,12 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
fileHash,
cachePaths
) => {
restoreCacheSpy.mockImplementation(
(cachePaths: string[], primaryKey: string, restoreKey?: string) => {
return primaryKey.includes(fileHash) ? primaryKey : '';
}
);
const cacheDistributor = getCacheDistributor(
packageManager,
pythonVersion,
@ -196,11 +201,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
30000
);
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']
])(
it.each([['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']])(
'Should throw an error because dependency file is not found',
async (
packageManager,
@ -213,13 +214,47 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
pythonVersion,
dependencyFile
);
await expect(cacheDistributor.restoreCache()).rejects.toThrowError(
await expect(cacheDistributor.restoreCache()).rejects.toThrow(
`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', () => {

View File

@ -87,6 +87,7 @@ 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();
@ -103,22 +104,7 @@ describe('run', () => {
it('should not save cache for pipenv', async () => {
inputs['cache'] = 'pipenv';
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';
inputs['python-version'] = '3.10.0';
await run();
@ -137,6 +123,7 @@ 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;
@ -163,6 +150,7 @@ 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;
@ -189,6 +177,7 @@ 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;
@ -215,6 +204,7 @@ 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;
@ -241,8 +231,9 @@ describe('run', () => {
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('saves with error from toolkit, should fail workflow', async () => {
it('saves with error from toolkit, should not fail the workflow', async () => {
inputs['cache'] = 'npm';
inputs['python-version'] = '3.10.0';
getStateSpy.mockImplementation((name: string) => {
if (name === State.STATE_CACHE_PRIMARY_KEY) {
return poetryLockHash;
@ -263,7 +254,7 @@ describe('run', () => {
expect(getStateSpy).toHaveBeenCalledTimes(3);
expect(infoSpy).not.toHaveBeenCalledWith();
expect(saveCacheSpy).toHaveBeenCalled();
expect(setFailedSpy).toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled();
});
});

View File

@ -1,4 +1,94 @@
[
{
"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",
@ -530,4 +620,4 @@
}
]
}
]
]

View File

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

View File

@ -17,7 +17,7 @@ import {
getPyPyVersionFromPath
} from '../src/utils';
const manifestData = require('./data/pypy.json');
import manifestData from './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)).toThrowError(
expect(() => finder.parsePyPyVersion(input)).toThrow(
"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)).toThrowError(
expect(() => finder.parsePyPyVersion(input)).toThrow(
"Invalid format of Python version for PyPy. Python version should be specified in format 'x.y'. See README for examples and documentation."
);
}
@ -273,7 +273,13 @@ describe('findPyPyVersion', () => {
it('found PyPy in toolcache', async () => {
await expect(
finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true, false)
finder.findPyPyVersion(
'pypy-3.6-v7.3.x',
architecture,
true,
false,
false
)
).resolves.toEqual({
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.3.3'
@ -291,13 +297,13 @@ describe('findPyPyVersion', () => {
it('throw on invalid input format', async () => {
await expect(
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false)
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, 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)
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false)
).rejects.toThrow();
});
@ -309,7 +315,13 @@ describe('findPyPyVersion', () => {
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, true, false)
finder.findPyPyVersion(
'pypy-3.7-v7.3.x',
architecture,
true,
false,
false
)
).resolves.toEqual({
resolvedPythonVersion: '3.7.9',
resolvedPyPyVersion: '7.3.3'
@ -333,7 +345,13 @@ describe('findPyPyVersion', () => {
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, false)
finder.findPyPyVersion(
'pypy-3.7-v7.3.x',
architecture,
false,
false,
false
)
).resolves.toEqual({
resolvedPythonVersion: '3.7.9',
resolvedPyPyVersion: '7.3.3'
@ -344,15 +362,27 @@ describe('findPyPyVersion', () => {
it('throw if release is not found', async () => {
await expect(
finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true, false)
).rejects.toThrowError(
finder.findPyPyVersion(
'pypy-3.7-v7.5.x',
architecture,
true,
false,
false
)
).rejects.toThrow(
`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)
finder.findPyPyVersion(
'pypy-3.6-v7.3.x',
architecture,
false,
true,
false
)
).resolves.toEqual({
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.3.3'
@ -371,7 +401,13 @@ describe('findPyPyVersion', () => {
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, true)
finder.findPyPyVersion(
'pypy-3.7-v7.3.x',
architecture,
false,
true,
false
)
).resolves.toEqual({
resolvedPythonVersion: '3.7.9',
resolvedPyPyVersion: '7.3.3'
@ -391,7 +427,13 @@ describe('findPyPyVersion', () => {
return pypyPath;
});
await expect(
finder.findPyPyVersion('pypy-3.8-v7.3.x', architecture, false, true)
finder.findPyPyVersion(
'pypy-3.8-v7.3.x',
architecture,
false,
true,
false
)
).resolves.toEqual({
resolvedPythonVersion: '3.8.8',
resolvedPyPyVersion: '7.3.3'
@ -401,4 +443,22 @@ 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

@ -24,7 +24,7 @@ import * as core from '@actions/core';
import * as finder from '../src/find-python';
import * as installer from '../src/install-python';
const manifestData = require('./data/versions-manifest.json');
import manifestData from './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);
await finder.useCpythonVersion('3.x', 'x64', true, false, 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);
await finder.useCpythonVersion('3.x', 'x64', false, false, false);
expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled();
});
@ -95,7 +95,12 @@ 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.3', 'x64', true, false);
await expect(
finder.useCpythonVersion('1.2.3', 'x64', true, false, false)
).resolves.toEqual({
impl: 'CPython',
version: '1.2.3'
});
expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation',
@ -122,14 +127,19 @@ describe('Finder tests', () => {
const pythonDir: string = path.join(
toolDir,
'Python',
'1.2.3-beta.2',
'1.2.4-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 finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, false);
await expect(
finder.useCpythonVersion('1.2.4-beta.2', 'x64', false, false, false)
).resolves.toEqual({
impl: 'CPython',
version: '1.2.4-beta.2'
});
});
it('Check-latest true, finds the latest version in the manifest', async () => {
@ -176,18 +186,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);
await finder.useCpythonVersion('1.2', 'x64', true, true, false);
expect(infoSpy).toHaveBeenCalledWith("Resolved as '1.2.3'");
expect(infoSpy).toHaveBeenCalledWith(
'Version 1.2.3 was not found in the local cache'
);
expect(infoSpy).toBeCalledWith(
expect(infoSpy).toHaveBeenCalledWith(
'Version 1.2.3 is available for downloading'
);
expect(installSpy).toHaveBeenCalled();
expect(addPathSpy).toHaveBeenCalledWith(expPath);
await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, true);
await finder.useCpythonVersion('1.2.4-beta.2', 'x64', false, true, false);
expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation',
@ -199,11 +209,67 @@ 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)
).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)
).rejects.toThrow();
await expect(
finder.useCpythonVersion('1.1', 'x64', false, false, true)
).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)
).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);
await finder.useCpythonVersion('3.300000', 'x64', true, false, false);
} catch {
thrown = true;
}

View File

@ -14,7 +14,7 @@ import {
IS_WINDOWS
} from '../src/utils';
const manifestData = require('./data/pypy.json');
import manifestData from './data/pypy.json';
let architecture: string;
if (IS_WINDOWS) {
@ -51,6 +51,12 @@ 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;
@ -72,7 +78,13 @@ describe('findRelease', () => {
const pythonVersion = '3.6';
const pypyVersion = '7.3.7';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual(null);
});
@ -80,7 +92,13 @@ describe('findRelease', () => {
const pythonVersion = '3.6';
const pypyVersion = '7.3.3';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({
foundAsset: files,
resolvedPythonVersion: '3.6.12',
@ -92,7 +110,13 @@ describe('findRelease', () => {
const pythonVersion = '3.6';
const pypyVersion = '7.x';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({
foundAsset: files,
resolvedPythonVersion: '3.6.12',
@ -104,7 +128,13 @@ describe('findRelease', () => {
const pythonVersion = '3.7';
const pypyVersion = installer.pypyVersionToSemantic('7.3.3rc2');
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({
foundAsset: {
filename: `test${extension}`,
@ -121,7 +151,13 @@ describe('findRelease', () => {
const pythonVersion = '3.6';
const pypyVersion = 'x';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({
foundAsset: files,
resolvedPythonVersion: '3.6.12',
@ -129,12 +165,45 @@ 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)
installer.findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
false
)
).toEqual({
foundAsset: {
filename: filename,
@ -224,8 +293,8 @@ describe('installPyPy', () => {
it('throw if release is not found', async () => {
await expect(
installer.installPyPy('7.3.3', '3.6.17', architecture, undefined)
).rejects.toThrowError(
installer.installPyPy('7.3.3', '3.6.17', architecture, false, undefined)
).rejects.toThrow(
`PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found`
);
@ -244,7 +313,7 @@ describe('installPyPy', () => {
spyChmodSync.mockImplementation(() => undefined);
await expect(
installer.installPyPy('7.3.x', '3.6.12', architecture, undefined)
installer.installPyPy('7.x', '3.6.12', architecture, false, undefined)
).resolves.toEqual({
installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture),
resolvedPythonVersion: '3.6.12',
@ -257,4 +326,31 @@ 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

@ -23,6 +23,9 @@ inputs:
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
outputs:
python-version:
description: "The installed Python or PyPy version. Useful when given a version range as input."

9069
dist/cache-save/index.js vendored

File diff suppressed because one or more lines are too long

10625
dist/setup/index.js vendored

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@
- [Linux](advanced-usage.md#linux)
- [macOS](advanced-usage.md#macos)
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
- [Allow pre-releases](advanced-usage.md#allow-pre-releases)
## Using the `python-version` input
@ -60,7 +61,7 @@ steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11.0-alpha.1'
python-version: '3.12.0-alpha.1'
- run: python my_script.py
```
@ -71,7 +72,7 @@ steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11-dev'
python-version: '3.12-dev'
- run: python my_script.py
```
@ -84,7 +85,7 @@ steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11.0-alpha - 3.11.0'
python-version: '3.12.0-alpha - 3.12.0'
- run: python my_script.py
```
@ -447,7 +448,7 @@ Such a requirement on side-effect could be because you don't want your composite
- For every minor version of Python, expect only the latest patch to be preinstalled.
- If `3.8.1` is installed for example, and `3.8.2` is released, expect `3.8.1` to be removed and replaced by `3.8.2` in the tool cache.
- If the exact patch version doesn't matter to you, specifying just the major and minor versions will get you the latest preinstalled patch version. In the previous example, the version spec `3.8` will use the `3.8.2` Python version found in the cache.
- Use `-dev` instead of a patch number (e.g., `3.11-dev`) to install the latest patch version release for a given minor version, *alpha and beta releases included*.
- Use `-dev` instead of a patch number (e.g., `3.12-dev`) to install the latest patch version release for a given minor version, *alpha and beta releases included*.
- Downloadable Python versions from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)).
- All available versions are listed in the [version-manifest.json](https://github.com/actions/python-versions/blob/main/versions-manifest.json) file.
- If there is a specific version of Python that is not available, you can open an issue here
@ -558,7 +559,7 @@ Here are the steps you need to follow to avoid the rate limit:
```yml
- name: Set up Python
uses: actions/setup-python@4
uses: actions/setup-python@v4
with:
python-version: 3.8
token: ${{ secrets.GH_GITHUB_COM_TOKEN }}
@ -567,4 +568,32 @@ Here are the steps you need to follow to avoid the rate limit:
Requests should now be authenticated. To verify that you are getting the higher rate limit, you can call GitHub's [rate limit API](https://docs.github.com/en/rest/rate-limit) from within your workflow ([example](https://github.com/actions/setup-python/pull/443#issuecomment-1206776401)).
### No access to github.com
If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.
If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.
## Allow pre-releases
The `allow-prereleases` flag defaults to `false`.
If `allow-prereleases` is set to `true`, the action will allow falling back to pre-release versions of Python when a matching GA version of Python is not available.
This allows for example to simplify reuse of `python-version` as an input of nox for pre-releases of Python by not requiring manipulation of the `3.y-dev` specifier.
For CPython, `allow-prereleases` will only have effect for `x.y` version range (e.g. `3.12`).
Let's say that python 3.12 is not generally available, the following workflow will fallback to the most recent pre-release of python 3.12:
```yaml
jobs:
test:
name: ${{ matrix.os }} / ${{ matrix.python_version }}
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [Ubuntu, Windows, macOS]
python_version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "${{ matrix.python_version }}"
- run: pipx run nox --error-on-missing-interpreters -s tests-${{ matrix.python_version }}
```

View File

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

2206
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,10 @@
"main": "dist/index.js",
"scripts": {
"build": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts",
"format": "prettier --write \"{,!(node_modules)/**/}*.ts\"",
"format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"",
"lint": "echo \"Fake command that does nothing. It is used in reusable workflows\"",
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"",
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check \"**/*.{ts,yml,yaml}\"",
"lint": "eslint --config ./.eslintrc.js \"**/*.ts\"",
"lint:fix": "eslint --config ./.eslintrc.js \"**/*.ts\" --fix",
"release": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts && git add -f dist/",
"test": "jest --coverage"
},
@ -36,11 +37,16 @@
"@types/jest": "^27.0.2",
"@types/node": "^16.11.25",
"@types/semver": "^7.1.0",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"@vercel/ncc": "^0.33.4",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.2.1",
"husky": "^7.0.2",
"jest": "^27.2.5",
"jest-circus": "^27.2.5",
"prettier": "^2.0.2",
"prettier": "^2.8.4",
"ts-jest": "^27.0.5",
"typescript": "^4.2.3"
},

View File

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

View File

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

View File

@ -8,11 +8,14 @@ import os from 'os';
import CacheDistributor from './cache-distributor';
import {getLinuxInfo, IS_LINUX, IS_WINDOWS} from '../utils';
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
class PipCache extends CacheDistributor {
private cacheDependencyBackupPath: string = CACHE_DEPENDENCY_BACKUP_PATH;
constructor(
private pythonVersion: string,
cacheDependencyPath: string = '**/requirements.txt'
cacheDependencyPath = '**/requirements.txt'
) {
super('pip', cacheDependencyPath);
}
@ -56,7 +59,9 @@ class PipCache extends CacheDistributor {
}
protected async computeKeys() {
const hash = await glob.hashFiles(this.cacheDependencyPath);
const hash =
(await glob.hashFiles(this.cacheDependencyPath)) ||
(await glob.hashFiles(this.cacheDependencyBackupPath));
let primaryKey = '';
let restoreKey = '';

View File

@ -17,7 +17,16 @@ export async function run() {
}
async function saveCache(packageManager: string) {
const cachePaths = JSON.parse(core.getState(State.CACHE_PATHS)) as string[];
const cachePathState = core.getState(State.CACHE_PATHS);
if (!cachePathState) {
core.warning(
'Cache paths are empty. Please check the previous logs and make sure that the python version is specified'
);
return;
}
const cachePaths = JSON.parse(cachePathState) as string[];
core.debug(`paths for caching are ${cachePaths.join(', ')}`);
@ -43,7 +52,16 @@ async function saveCache(packageManager: string) {
return;
}
const cacheId = await cache.saveCache(cachePaths, primaryKey);
let cacheId = 0;
try {
cacheId = await cache.saveCache(cachePaths, primaryKey);
} catch (err) {
const message = (err as Error).message;
core.info(`[warning]${message}`);
return;
}
if (cacheId == -1) {
return;
}

View File

@ -23,7 +23,8 @@ export async function findPyPyVersion(
versionSpec: string,
architecture: string,
updateEnvironment: boolean,
checkLatest: boolean
checkLatest: boolean,
allowPreReleases: boolean
): Promise<{resolvedPyPyVersion: string; resolvedPythonVersion: string}> {
let resolvedPyPyVersion = '';
let resolvedPythonVersion = '';
@ -39,7 +40,8 @@ export async function findPyPyVersion(
releases,
pypyVersionSpec.pythonVersion,
pypyVersionSpec.pypyVersion,
architecture
architecture,
false
);
if (releaseData) {
@ -63,16 +65,14 @@ export async function findPyPyVersion(
));
if (!installDir) {
({
installDir,
resolvedPythonVersion,
resolvedPyPyVersion
} = await pypyInstall.installPyPy(
pypyVersionSpec.pypyVersion,
pypyVersionSpec.pythonVersion,
architecture,
releases
));
({installDir, resolvedPythonVersion, resolvedPyPyVersion} =
await pypyInstall.installPyPy(
pypyVersionSpec.pypyVersion,
pypyVersionSpec.pythonVersion,
architecture,
allowPreReleases,
releases
));
}
const pipDir = IS_WINDOWS ? 'Scripts' : 'bin';
@ -95,7 +95,7 @@ export async function findPyPyVersion(
core.addPath(pythonLocation);
core.addPath(_binDir);
}
core.setOutput('python-version', 'pypy' + resolvedPyPyVersion.trim());
core.setOutput('python-version', 'pypy' + resolvedPyPyVersion);
core.setOutput('python-path', pythonPath);
return {resolvedPyPyVersion, resolvedPythonVersion};
@ -142,7 +142,7 @@ export function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec {
const versions = versionSpec.split('-').filter(item => !!item);
if (/^(pypy)(.+)/.test(versions[0])) {
let pythonVersion = versions[0].replace('pypy', '');
const pythonVersion = versions[0].replace('pypy', '');
versions.splice(0, 1, 'pypy', pythonVersion);
}

View File

@ -34,11 +34,15 @@ export async function useCpythonVersion(
version: string,
architecture: string,
updateEnvironment: boolean,
checkLatest: boolean
checkLatest: boolean,
allowPreReleases: boolean
): Promise<InstalledVersion> {
let manifest: tc.IToolRelease[] | null = null;
const desugaredVersionSpec = desugarDevVersion(version);
let semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec);
let semanticVersionSpec = pythonVersionToSemantic(
desugaredVersionSpec,
allowPreReleases
);
core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`);
if (checkLatest) {
@ -178,8 +182,18 @@ interface InstalledVersion {
* Python's prelease versions look like `3.7.0b2`.
* This is the one part of Python versioning that does not look like semantic versioning, which specifies `3.7.0-b2`.
* If the version spec contains prerelease versions, we need to convert them to the semantic version equivalent.
*
* For easier use of the action, we also map 'x.y' to allow pre-release before 'x.y.0' release if allowPreReleases is true
*/
export function pythonVersionToSemantic(versionSpec: string) {
export function pythonVersionToSemantic(
versionSpec: string,
allowPreReleases: boolean
) {
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc)\d*)/g;
return versionSpec.replace(prereleaseVersion, '$1-$2');
const majorMinor = /^(\d+)\.(\d+)$/;
let result = versionSpec.replace(prereleaseVersion, '$1-$2');
if (allowPreReleases) {
result = result.replace(majorMinor, '~$1.$2.0-0');
}
return result;
}

View File

@ -1,3 +1,4 @@
import * as os from 'os';
import * as path from 'path';
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
@ -19,6 +20,7 @@ export async function installPyPy(
pypyVersion: string,
pythonVersion: string,
architecture: string,
allowPreReleases: boolean,
releases: IPyPyManifestRelease[] | undefined
) {
let downloadDir;
@ -29,13 +31,31 @@ export async function installPyPy(
throw new Error('No release was found in PyPy version.json');
}
const releaseData = findRelease(
let releaseData = findRelease(
releases,
pythonVersion,
pypyVersion,
architecture
architecture,
false
);
if (allowPreReleases && (!releaseData || !releaseData.foundAsset)) {
// check for pre-release
core.info(
[
`Stable PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`,
`Trying pre-release versions`
].join(os.EOL)
);
releaseData = findRelease(
releases,
pythonVersion,
pypyVersion,
architecture,
true
);
}
if (!releaseData || !releaseData.foundAsset) {
throw new Error(
`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`
@ -43,7 +63,7 @@ export async function installPyPy(
}
const {foundAsset, resolvedPythonVersion, resolvedPyPyVersion} = releaseData;
let downloadUrl = `${foundAsset.download_url}`;
const downloadUrl = `${foundAsset.download_url}`;
core.info(`Downloading PyPy from "${downloadUrl}" ...`);
@ -123,7 +143,7 @@ async function createPyPySymlink(
const pythonMinor = semver.minor(version);
const pypyBinaryPostfix = pythonBinaryPostfix === 2 ? '' : '3';
const pypyMajorMinorBinaryPostfix = `${pythonBinaryPostfix}.${pythonMinor}`;
let binaryExtension = IS_WINDOWS ? '.exe' : '';
const binaryExtension = IS_WINDOWS ? '.exe' : '';
core.info('Creating symlinks...');
createSymlinkInFolder(
@ -162,8 +182,10 @@ export function findRelease(
releases: IPyPyManifestRelease[],
pythonVersion: string,
pypyVersion: string,
architecture: string
architecture: string,
includePrerelease: boolean
) {
const options = {includePrerelease: includePrerelease};
const filterReleases = releases.filter(item => {
const isPythonVersionSatisfied = semver.satisfies(
semver.coerce(item.python_version)!,
@ -173,7 +195,11 @@ export function findRelease(
isNightlyKeyword(pypyVersion) && isNightlyKeyword(item.pypy_version);
const isPyPyVersionSatisfied =
isPyPyNightly ||
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
semver.satisfies(
pypyVersionToSemantic(item.pypy_version),
pypyVersion,
options
);
const isArchPresent =
item.files &&
(IS_WINDOWS
@ -207,7 +233,7 @@ export function findRelease(
return {
foundAsset,
resolvedPythonVersion: foundRelease.python_version,
resolvedPyPyVersion: foundRelease.pypy_version
resolvedPyPyVersion: foundRelease.pypy_version.trim()
};
}

View File

@ -23,7 +23,7 @@ async function cacheDependencies(cache: string, pythonVersion: string) {
}
function resolveVersionInput() {
let versions = core.getMultilineInput('python-version');
const versions = core.getMultilineInput('python-version');
let versionFile = core.getInput('python-version-file');
if (versions.length && versionFile) {
@ -77,6 +77,7 @@ async function run() {
try {
const versions = resolveVersionInput();
const checkLatest = core.getBooleanInput('check-latest');
const allowPreReleases = core.getBooleanInput('allow-prereleases');
if (versions.length) {
let pythonVersion = '';
@ -89,7 +90,8 @@ async function run() {
version,
arch,
updateEnvironment,
checkLatest
checkLatest,
allowPreReleases
);
pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`;
core.info(
@ -100,7 +102,8 @@ async function run() {
version,
arch,
updateEnvironment,
checkLatest
checkLatest,
allowPreReleases
);
pythonVersion = installed.version;
core.info(`Successfully set up ${installed.impl} (${pythonVersion})`);

View File

@ -1,3 +1,4 @@
/* eslint no-unsafe-finally: "off" */
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import fs from 'fs';
@ -71,9 +72,9 @@ export function getPyPyVersionFromPath(installDir: string) {
*/
export function readExactPyPyVersionFile(installDir: string) {
let pypyVersion = '';
let fileVersion = path.join(installDir, PYPY_VERSION_FILE);
const fileVersion = path.join(installDir, PYPY_VERSION_FILE);
if (fs.existsSync(fileVersion)) {
pypyVersion = fs.readFileSync(fileVersion).toString();
pypyVersion = fs.readFileSync(fileVersion).toString().trim();
}
return pypyVersion;

View File

@ -45,7 +45,8 @@
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"resolveJsonModule": true, /* Allows importing modules with a '.json' extension, which is a common practice in node projects. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */

View File

@ -1,7 +0,0 @@
extends: default
rules:
# 120 chars should be enough, but don't fail if a line is longer
line-length:
max: 120
level: warning