mirror of
https://github.com/actions/setup-python.git
synced 2026-09-17 10:01:28 +00:00
Compare commits
283
Commits
v2.2.1
...
testensure
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bc8944241 | ||
|
|
a0d74c0c42 | ||
|
|
4eb7dbcb95 | ||
|
|
82c7e631bb | ||
|
|
10aa35afd7 | ||
|
|
9a7ac94420 | ||
|
|
871daa956c | ||
|
|
2f078955e4 | ||
|
|
e9d6f99097 | ||
|
|
0a5c615913 | ||
|
|
0ae58361cd | ||
|
|
b64ffcaf5b | ||
|
|
8d2896179a | ||
|
|
7bc6abb01e | ||
|
|
e8111cec9d | ||
|
|
a00ea43da6 | ||
|
|
8635b1ccc5 | ||
|
|
f6cc428f53 | ||
|
|
5f2af211d6 | ||
|
|
3467d92d48 | ||
|
|
65d7f2d534 | ||
|
|
f97b83114c | ||
|
|
61a6322f88 | ||
|
|
ea5b57fccc | ||
|
|
014d32a830 | ||
|
|
c16c4b8d18 | ||
|
|
0d5da6a89a | ||
|
|
3f824b7ca6 | ||
|
|
bd6b4b6205 | ||
|
|
0cbcb9a3d7 | ||
|
|
669664dac1 | ||
|
|
9cbf792a3c | ||
|
|
e732e40717 | ||
|
|
a0d867bfa9 | ||
|
|
d99bed8b21 | ||
|
|
f71253fee3 | ||
|
|
b51c97f6e3 | ||
|
|
db9987b4c1 | ||
|
|
6db7460265 | ||
|
|
57ded4d7d5 | ||
|
|
df6abcc733 | ||
|
|
7a4f344e33 | ||
|
|
d1244c8404 | ||
|
|
3091b37310 | ||
|
|
dfa76f8d0d | ||
|
|
03eb867e3d | ||
|
|
b41aaf9f0c | ||
|
|
0ffa49cfca | ||
|
|
ec365b4eba | ||
|
|
7b9ef6fc5a | ||
|
|
869e769ec8 | ||
|
|
3faddefb4c | ||
|
|
181184007f | ||
|
|
2652534ead | ||
|
|
a6eba85bba | ||
|
|
34b4b622e3 | ||
|
|
f60fe39c45 | ||
|
|
d27e3f3d7c | ||
|
|
dec86ecf4e | ||
|
|
4dcd67678f | ||
|
|
8b89ef08a0 | ||
|
|
5ccb29d877 | ||
|
|
c3e033939c | ||
|
|
206e984b94 | ||
|
|
2c3dd9e7e2 | ||
|
|
76bbdfadd7 | ||
|
|
1aafadcfb9 | ||
|
|
b80efd6bc5 | ||
|
|
5cddb27885 | ||
|
|
47c4a7af1d | ||
|
|
af57b64994 | ||
|
|
4818a5a153 | ||
|
|
8bcd2560e2 | ||
|
|
13ae5bb136 | ||
|
|
0c4d7b878c | ||
|
|
13a464fa11 | ||
|
|
b4fe97ecda | ||
|
|
434aeabbb4 | ||
|
|
98c991d13f | ||
|
|
397a35f988 | ||
|
|
48a0f006ff | ||
|
|
978fd06d1f | ||
|
|
050e616f66 | ||
|
|
f6795b163d | ||
|
|
2e6ca74422 | ||
|
|
aa5ddbf8fe | ||
|
|
c0abeaa470 | ||
|
|
197204a31c | ||
|
|
c96b4b55f3 | ||
|
|
b55428b188 | ||
|
|
e084fcae44 | ||
|
|
789730b666 | ||
|
|
c4e98b741b | ||
|
|
cfcafa57ec | ||
|
|
9aa1c6cb27 | ||
|
|
c318b92fd6 | ||
|
|
a93d5412cb | ||
|
|
72394d1a3e | ||
|
|
fe396d3941 | ||
|
|
853c012a3c | ||
|
|
fd6f59db22 | ||
|
|
c6e66a7681 | ||
|
|
81cda82fb0 | ||
|
|
7e39d25e3f | ||
|
|
d5d67707d2 | ||
|
|
bc8ee42330 | ||
|
|
467a981225 | ||
|
|
9f1915a970 | ||
|
|
10b840936c | ||
|
|
b152b04c28 | ||
|
|
a624f1f4bc | ||
|
|
5df6377e9d | ||
|
|
dd40245e5b | ||
|
|
1f0a39a525 | ||
|
|
b2241a4754 | ||
|
|
0d94a5d71e | ||
|
|
e147df2e90 | ||
|
|
889226ae9a | ||
|
|
00d9c42868 | ||
|
|
2f06e9da25 | ||
|
|
49a521fa06 | ||
|
|
592a7a7a45 | ||
|
|
aba6f4ba7b | ||
|
|
5517d5f7b5 | ||
|
|
b88a682917 | ||
|
|
c474c82340 | ||
|
|
799afeb796 | ||
|
|
386e4eaaed | ||
|
|
61fb4e42ab | ||
|
|
09086ccd46 | ||
|
|
746f28a2d3 | ||
|
|
6dd8ff72eb | ||
|
|
9a40041e25 | ||
|
|
c4e89fac7e | ||
|
|
0ad0f6a0a5 | ||
|
|
f0bcf8be03 | ||
|
|
af97157ae6 | ||
|
|
364e819741 | ||
|
|
782f81b91d | ||
|
|
b318cecd93 | ||
|
|
4a7ca55b40 | ||
|
|
d08a9d79f1 | ||
|
|
7d9c63da1b | ||
|
|
5a1dd6b34d | ||
|
|
f4b85ae24e | ||
|
|
2c9de4ed41 | ||
|
|
412091c1e0 | ||
|
|
78a2330b92 | ||
|
|
96f494e18c | ||
|
|
099ed898be | ||
|
|
ccb7da8ae9 | ||
|
|
5fbb819407 | ||
|
|
82eddc4023 | ||
|
|
d97b6edda3 | ||
|
|
a6b01c4e40 | ||
|
|
84087f5301 | ||
|
|
56f6060254 | ||
|
|
e29a7c89f6 | ||
|
|
5407bf6e69 | ||
|
|
41b91104ea | ||
|
|
08116500d0 | ||
|
|
161c3a68f0 | ||
|
|
6733fc44ec | ||
|
|
afd3e72a25 | ||
|
|
ab6deb310f | ||
|
|
e629242ad4 | ||
|
|
63086c6ded | ||
|
|
69b94463f5 | ||
|
|
d7db8259d9 | ||
|
|
27091d50ca | ||
|
|
d358f9e3d7 | ||
|
|
1e52de40a4 | ||
|
|
2a20d9b5e0 | ||
|
|
766e8c6088 | ||
|
|
00a5248c77 | ||
|
|
9c76df2a90 | ||
|
|
958897304a | ||
|
|
5d9fdcab75 | ||
|
|
7199395312 | ||
|
|
5ad79022bc | ||
|
|
a8da2a66aa | ||
|
|
c61bc3d08e | ||
|
|
01408cef88 | ||
|
|
ffcd00020c | ||
|
|
cf86e08a31 | ||
|
|
8fb4cbf7c8 | ||
|
|
7e4abae443 | ||
|
|
813f9b1556 | ||
|
|
775367df99 | ||
|
|
d09bd5e600 | ||
|
|
f72db171ab | ||
|
|
53e15292cd | ||
|
|
3f82819745 | ||
|
|
397252c582 | ||
|
|
de977ad132 | ||
|
|
22c6af91ce | ||
|
|
081a3cf1a5 | ||
|
|
ff706563d7 | ||
|
|
fff15a21cc | ||
|
|
c57f79353b | ||
|
|
fd8f0a9fb8 | ||
|
|
ae11205ec6 | ||
|
|
8f73c1495f | ||
|
|
e31727ce0a | ||
|
|
a69041ca9f | ||
|
|
5e1e05c694 | ||
|
|
0b56b76337 | ||
|
|
22daa094b8 | ||
|
|
ac4e858835 | ||
|
|
1ce308808a | ||
|
|
c36dc43e7b | ||
|
|
4e6b5f40fc | ||
|
|
bcc31375e1 | ||
|
|
85a7430316 | ||
|
|
6a4c6c1309 | ||
|
|
3a63f5d525 | ||
|
|
4a33d3c467 | ||
|
|
abfd16b121 | ||
|
|
4176166af9 | ||
|
|
91712e11bb | ||
|
|
98f2ad02fd | ||
|
|
5d6f0c8a87 | ||
|
|
f4b66dec00 | ||
|
|
21c0493ecf | ||
|
|
7933d5a3dd | ||
|
|
7885ec3539 | ||
|
|
9c644ca2ab | ||
|
|
3e8e90edf0 | ||
|
|
05fb98de9a | ||
|
|
6c566026c0 | ||
|
|
9516be869f | ||
|
|
7aa3e95001 | ||
|
|
6c31eb3fc7 | ||
|
|
7a37d78806 | ||
|
|
e4be7a40b0 | ||
|
|
aac0ef93ba | ||
|
|
b0c8e3dab7 | ||
|
|
0ebf7997c4 | ||
|
|
415c3568c9 | ||
|
|
42ed863652 | ||
|
|
c275cf49c7 | ||
|
|
7c950ebdca | ||
|
|
1259541ec8 | ||
|
|
95824fd246 | ||
|
|
59cb3f4919 | ||
|
|
18c67b44e4 | ||
|
|
bbebfafece | ||
|
|
6c048c7558 | ||
|
|
0ff64a7f0e | ||
|
|
792c23f43e | ||
|
|
8c1441c007 | ||
|
|
0ebf233433 | ||
|
|
665cd78205 | ||
|
|
93cb78f17b | ||
|
|
65fe6a82c7 | ||
|
|
011c443f81 | ||
|
|
3250b5373c | ||
|
|
7f80679172 | ||
|
|
dc9de69ff3 | ||
|
|
ba33a692f1 | ||
|
|
156361d073 | ||
|
|
0bcf8ef2ba | ||
|
|
9a115684c9 | ||
|
|
3a40ba0199 | ||
|
|
fa17801fa7 | ||
|
|
6277dd1255 | ||
|
|
2b732b899c | ||
|
|
f382193329 | ||
|
|
3ef38b826b | ||
|
|
0066b88440 | ||
|
|
280924fbef | ||
|
|
52636cf49a | ||
|
|
ca5c59064f | ||
|
|
feeaa3ba49 | ||
|
|
002b1e4044 | ||
|
|
d12543aa2a | ||
|
|
4aa563ba8c | ||
|
|
70e2063f71 | ||
|
|
2d803e7fea | ||
|
|
43c2dc443f | ||
|
|
dc73133d4d | ||
|
|
a1121449a2 | ||
|
|
66319ca9fa |
@@ -0,0 +1,6 @@
|
|||||||
|
# Ignore list
|
||||||
|
/*
|
||||||
|
|
||||||
|
# Do not ignore these folders:
|
||||||
|
!__tests__/
|
||||||
|
!src/
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||||
|
module.exports = {
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:eslint-plugin-jest/recommended',
|
||||||
|
'eslint-config-prettier'
|
||||||
|
],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
plugins: ['@typescript-eslint', 'eslint-plugin-node', 'eslint-plugin-jest'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-require-imports': 'error',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
|
'@typescript-eslint/ban-ts-comment': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'ts-ignore': 'allow-with-description'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'no-console': 'error',
|
||||||
|
'yoda': 'error',
|
||||||
|
'prefer-const': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
destructuring: 'all'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'no-control-regex': 'off',
|
||||||
|
'no-constant-condition': ['error', {checkLoops: false}],
|
||||||
|
'node/no-extraneous-import': 'error'
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['**/*{test,spec}.ts'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
|
'jest/no-standalone-expect': 'off',
|
||||||
|
'jest/no-conditional-expect': 'off',
|
||||||
|
'no-console': 'off',
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
es6: true,
|
||||||
|
'jest/globals': true
|
||||||
|
}
|
||||||
|
};
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
* @actions/actions-service
|
* @actions/setup-actions-team
|
||||||
|
|||||||
@@ -1,44 +1,38 @@
|
|||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve
|
about: Create a bug report
|
||||||
title: ''
|
title: ''
|
||||||
labels: bug
|
labels: bug, needs triage
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
|
||||||
|
<!--- Before opening up a new bug report, please make sure to check for similar existing issues -->
|
||||||
|
|
||||||
|
**Description:**
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
**Which version of the action are you using?**
|
**Action version:**
|
||||||
|
Specify the action version
|
||||||
|
|
||||||
- [ ] `v1`
|
**Platform:**
|
||||||
- [ ] `v2`
|
- [ ] Ubuntu
|
||||||
- [ ] Some other tag (such as `v2.0.1` or `master`)
|
- [ ] macOS
|
||||||
|
|
||||||
**Environment**
|
|
||||||
- [ ] self-hosted
|
|
||||||
- [ ] Linux
|
|
||||||
- [ ] Windows
|
- [ ] Windows
|
||||||
- [ ] Mac
|
|
||||||
|
|
||||||
If applicable, please specify if you're using a container
|
**Runner type:**
|
||||||
|
- [ ] Hosted
|
||||||
|
- [ ] Self-hosted
|
||||||
|
|
||||||
**Python Versions**
|
**Tools version:**
|
||||||
Please list all of the effected versions of Python (`3.8.2`, etc.)
|
<!--- Please list all of the affected Python versions (`3.8.2`, etc.)-->
|
||||||
|
|
||||||
**To Reproduce**
|
**Repro steps:**
|
||||||
Steps to reproduce the behavior:
|
A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link.
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Run/Repo Url**
|
**Expected behavior:**
|
||||||
If applicable, and if your repo/run is public, please include a URL so it is easier for us to investigate.
|
A description of what you expected to happen.
|
||||||
|
|
||||||
**Screenshots**
|
**Actual behavior:**
|
||||||
If applicable, add screenshots to help explain your problem.
|
A description of what is actually happening.
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: feature request, needs triage
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
|
||||||
|
<!--- Before opening up a new feature request, please make sure to check for similar existing issues and pull requests -->
|
||||||
|
|
||||||
|
**Description:**
|
||||||
|
Describe your proposal.
|
||||||
|
|
||||||
|
**Justification:**
|
||||||
|
Justification or a use case for your proposal.
|
||||||
|
|
||||||
|
**Are you willing to submit a PR?**
|
||||||
|
<!--- We accept contributions! -->
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
**Description:**
|
||||||
|
Describe your changes.
|
||||||
|
|
||||||
|
**Related issue:**
|
||||||
|
Add link to the related issue.
|
||||||
|
|
||||||
|
**Check list:**
|
||||||
|
- [ ] Mark if documentation changes are required.
|
||||||
|
- [ ] Mark if tests were added or updated to cover the changes.
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
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'
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: Check dist/
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-check-dist:
|
||||||
|
name: Check dist/
|
||||||
|
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
@@ -1,45 +1,13 @@
|
|||||||
name: "Code scanning - action"
|
name: CodeQL analysis
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches: ['main']
|
||||||
|
pull_request:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '25 3 * * 5'
|
- cron: '0 3 * * 0'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
CodeQL-Build:
|
call-codeQL-analysis:
|
||||||
|
name: CodeQL analysis
|
||||||
strategy:
|
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
# CodeQL runs on ubuntu-latest and windows-latest
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v1
|
|
||||||
# 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@v1
|
|
||||||
|
|
||||||
# ℹ️ 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@v1
|
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
name: e2e-cache
|
||||||
|
|
||||||
|
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, windows-latest, macos-latest]
|
||||||
|
python-version: ['3.9', 'pypy-3.9-v7.x']
|
||||||
|
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, windows-latest, macos-latest]
|
||||||
|
python-version: ['3.9', 'pypy-3.9-v7.x']
|
||||||
|
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: Prepare environment
|
||||||
|
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
|
||||||
|
} else {
|
||||||
|
pipenv install --python ${{ matrix.python-version }} # --keep-outdated
|
||||||
|
}
|
||||||
|
- name: Run Python Script
|
||||||
|
run: pipenv run python test-pipenv.py
|
||||||
|
|
||||||
|
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, windows-latest, macos-latest]
|
||||||
|
python-version: ['3.9', 'pypy-3.9']
|
||||||
|
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 }}
|
||||||
|
cache: 'poetry'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: poetry install
|
||||||
|
|
||||||
|
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, windows-latest, macos-latest]
|
||||||
|
python-version: ['3.9', 'pypy-3.9-v7.x']
|
||||||
|
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, windows-latest, macos-latest]
|
||||||
|
python-version: ['3.9', 'pypy-3.9-v7.x']
|
||||||
|
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: Prepare environment
|
||||||
|
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
|
||||||
|
} else {
|
||||||
|
pipenv install --python ${{ matrix.python-version }} # --keep-outdated
|
||||||
|
}
|
||||||
|
- name: Run Python Script
|
||||||
|
run: pipenv run python test-pipenv.py
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
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: [ubuntu-20.04, windows-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- 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.10
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: 3.8.10
|
||||||
|
- name: Verify 3.8.10
|
||||||
|
run: python __tests__/verify-python.py 3.8.10
|
||||||
|
|
||||||
|
- 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.4
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: 3.12.4
|
||||||
|
- name: Verify 3.12.4
|
||||||
|
run: python __tests__/verify-python.py 3.12.4
|
||||||
|
|
||||||
|
- 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.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.11
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: '<3.11'
|
||||||
|
- name: Verify <3.11
|
||||||
|
run: python __tests__/verify-python.py 3.10
|
||||||
|
- name: Test Raw Endpoint Access
|
||||||
|
run: |
|
||||||
|
curl -L https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json | jq empty
|
||||||
|
shell: bash
|
||||||
@@ -1,20 +1,14 @@
|
|||||||
name: Licensed
|
name: Licensed
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push: {branches: main}
|
push:
|
||||||
pull_request: {branches: main}
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
call-licensed:
|
||||||
runs-on: ubuntu-latest
|
name: Licensed
|
||||||
name: Check licenses
|
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: npm ci
|
|
||||||
- name: Install licensed
|
|
||||||
run: |
|
|
||||||
cd $RUNNER_TEMP
|
|
||||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
|
|
||||||
sudo tar -xzf licensed.tar.gz
|
|
||||||
sudo mv licensed /usr/local/bin/licensed
|
|
||||||
- run: licensed status
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
name: Release new action version
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [released]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
TAG_NAME:
|
||||||
|
description: 'Tag name that the major tag will point to'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_tag:
|
||||||
|
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
||||||
|
environment:
|
||||||
|
name: releaseNewActionVersion
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- 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 }}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
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-20.04, ubuntu-latest]
|
||||||
|
graalpy:
|
||||||
|
- 'graalpy-23.0'
|
||||||
|
- 'graalpy-22.3'
|
||||||
|
|
||||||
|
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-20.04, ubuntu-latest]
|
||||||
|
graalpy: ['graalpy23.0', 'graalpy22.3']
|
||||||
|
|
||||||
|
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]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup GraalPy and check latest
|
||||||
|
uses: ./
|
||||||
|
id: graalpy
|
||||||
|
with:
|
||||||
|
python-version: 'graalpy-23.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
|
||||||
+134
-11
@@ -1,4 +1,5 @@
|
|||||||
name: Validate PyPy e2e
|
name: Validate PyPy e2e
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -10,6 +11,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: 30 3 * * *
|
- cron: 30 3 * * *
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
setup-pypy:
|
setup-pypy:
|
||||||
@@ -18,30 +20,151 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
|
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-latest]
|
||||||
pypy:
|
pypy:
|
||||||
- 'pypy-2.7'
|
- 'pypy-2.7'
|
||||||
- 'pypy-3.6'
|
- 'pypy-3.10'
|
||||||
- 'pypy-3.7'
|
- 'pypy3.9'
|
||||||
- 'pypy-2.7-v7.3.2'
|
- 'pypy-2.7-v7.3.14'
|
||||||
- 'pypy-3.6-v7.3.2'
|
- 'pypy-3.10-v7.3.15'
|
||||||
- 'pypy-3.7-v7.3.2'
|
- 'pypy-3.10-v7.3.14'
|
||||||
- 'pypy-3.6-v7.3.x'
|
- 'pypy-3.10-v7.3.x'
|
||||||
- 'pypy-3.7-v7.x'
|
- 'pypy-3.10-v7.x'
|
||||||
- 'pypy-3.6-v7.3.3rc1'
|
- 'pypy-2.7-v7.3.12rc1'
|
||||||
- 'pypy-3.7-nightly'
|
- 'pypy-3.10-nightly'
|
||||||
|
- 'pypy3.10-v7.3.15'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: setup-python ${{ matrix.pypy }}
|
- name: setup-python ${{ matrix.pypy }}
|
||||||
|
id: setup-python
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.pypy }}
|
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
|
- name: PyPy and Python version
|
||||||
run: python --version
|
run: python --version
|
||||||
|
|
||||||
- name: Run simple code
|
- name: Run simple code
|
||||||
run: python -c 'import math; print(math.factorial(5))'
|
run: python -c 'import math; print(math.factorial(5))'
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
setup-pypy-noenv:
|
||||||
|
name: Setup PyPy ${{ matrix.pypy }} ${{ matrix.os }} (noenv)
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-latest]
|
||||||
|
pypy: ['pypy2.7', 'pypy3.9', 'pypy3.10-nightly']
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: setup-python ${{ matrix.pypy }}
|
||||||
|
id: setup-python
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.pypy }}
|
||||||
|
update-environment: false
|
||||||
|
|
||||||
|
- name: PyPy 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, windows-latest, macos-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup PyPy and check latest
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: 'pypy-3.10-v7.3.x'
|
||||||
|
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.10-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: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup PyPy and check latest
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: |
|
||||||
|
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.10-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
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
name: Validate Python e2e
|
name: Validate Python e2e
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -10,45 +11,202 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: 30 3 * * *
|
- cron: 30 3 * * *
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
default-version:
|
|
||||||
name: Setup default version
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: setup default python
|
|
||||||
uses: ./
|
|
||||||
|
|
||||||
- name: Validate version
|
|
||||||
run: python --version
|
|
||||||
|
|
||||||
- name: Run simple python code
|
|
||||||
run: python -c 'import math; print(math.factorial(5))'
|
|
||||||
|
|
||||||
setup-versions-from-manifest:
|
setup-versions-from-manifest:
|
||||||
name: Setup ${{ matrix.python }} ${{ matrix.os }}
|
name: Setup ${{ matrix.python }} ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
|
||||||
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
|
python: [3.8.10, 3.9.13, 3.10.11, 3.11.9, 3.12.3]
|
||||||
|
exclude:
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
python: 3.8.10
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: setup-python ${{ matrix.python }}
|
- name: setup-python ${{ matrix.python }}
|
||||||
|
id: setup-python
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python }}
|
python-version: ${{ matrix.python }}
|
||||||
|
|
||||||
|
- 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-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]
|
||||||
|
python: [3.8.10, 3.9.13, 3.10.11, 3.11.9, 3.12.3]
|
||||||
|
exclude:
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
python: 3.8.10
|
||||||
|
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: 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-20.04, ubuntu-22.04]
|
||||||
|
python: [3.8.10, 3.9.13, 3.10.11, 3.11.9, 3.12.3]
|
||||||
|
exclude:
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
python: 3.8.10
|
||||||
|
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-20.04, ubuntu-22.04]
|
||||||
|
python: [3.8.10, 3.9.13, 3.10.11, 3.11.9, '==3.12.3']
|
||||||
|
exclude:
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
python: 3.8.10
|
||||||
|
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-20.04, ubuntu-22.04]
|
||||||
|
python: [3.8.10, 3.9.13, 3.10.11, 3.11.9, 3.12.3]
|
||||||
|
exclude:
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
python: 3.8.10
|
||||||
|
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
|
- name: Validate version
|
||||||
run: |
|
run: |
|
||||||
$pythonVersion = (python --version)
|
$pythonVersion = (python --version)
|
||||||
@@ -63,26 +221,31 @@ jobs:
|
|||||||
run: python -c 'import math; print(math.factorial(5))'
|
run: python -c 'import math; print(math.factorial(5))'
|
||||||
|
|
||||||
setup-pre-release-version-from-manifest:
|
setup-pre-release-version-from-manifest:
|
||||||
name: Setup 3.9.0-beta.4 ${{ matrix.os }}
|
name: Setup 3.13.0-alpha.6 ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: setup-python 3.9.0-beta.4
|
- name: setup-python 3.13.0-alpha.6
|
||||||
|
id: setup-python
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
python-version: '3.9.0-beta.4'
|
python-version: '3.13.0-alpha.6'
|
||||||
|
|
||||||
|
- name: Check python-path
|
||||||
|
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Validate version
|
- name: Validate version
|
||||||
run: |
|
run: |
|
||||||
$pythonVersion = (python --version)
|
$pythonVersion = (python --version)
|
||||||
if ("Python 3.9.0b4" -ne "$pythonVersion"){
|
if ("Python 3.13.0a6" -ne "$pythonVersion"){
|
||||||
Write-Host "The current version is $pythonVersion; expected version is 3.9.0b4"
|
Write-Host "The current version is $pythonVersion; expected version is 3.13.0a6"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
$pythonVersion
|
$pythonVersion
|
||||||
@@ -91,23 +254,136 @@ jobs:
|
|||||||
- name: Run simple code
|
- name: Run simple code
|
||||||
run: python -c 'import math; print(math.factorial(5))'
|
run: python -c 'import math; print(math.factorial(5))'
|
||||||
|
|
||||||
setup-pypy-legacy:
|
setup-dev-version:
|
||||||
name: Setup PyPy ${{ matrix.os }}
|
name: Setup 3.13-dev ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: setup-python pypy3
|
- name: setup-python 3.13-dev
|
||||||
|
id: setup-python
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
python-version: 'pypy3'
|
python-version: '3.13-dev'
|
||||||
|
|
||||||
- name: setup-python pypy2
|
- 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.13.') }}
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Run simple code
|
||||||
|
run: python -c 'import math; print(math.factorial(5))'
|
||||||
|
|
||||||
|
setup-prerelease-version:
|
||||||
|
name: Setup 3.13 ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: setup-python 3.13
|
||||||
|
id: setup-python
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
python-version: 'pypy2'
|
python-version: '3.13'
|
||||||
|
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.13.') }}
|
||||||
|
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]
|
||||||
|
python: ['3.8', '3.9', '3.10', '3.11', '3.12']
|
||||||
|
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: 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, windows-latest, macos-latest]
|
||||||
|
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup Python and check latest
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
check-latest: true
|
||||||
|
- 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 }}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$pythonVersion
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
setup-python-multiple-python-versions:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup Python and check latest
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: |
|
||||||
|
3.8
|
||||||
|
3.9
|
||||||
|
3.10
|
||||||
|
3.11
|
||||||
|
3.12
|
||||||
|
check-latest: true
|
||||||
|
- name: Validate version
|
||||||
|
run: |
|
||||||
|
$pythonVersion = (python --version)
|
||||||
|
if ("$pythonVersion" -NotMatch "3.12"){
|
||||||
|
Write-Host "The current version is $pythonVersion; expected version is 3.12"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$pythonVersion
|
||||||
|
shell: pwsh
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
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@v2
|
|
||||||
|
|
||||||
- name: Set Node.js 12.x
|
|
||||||
uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 12.x
|
|
||||||
|
|
||||||
- name: npm install
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- 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
|
|
||||||
@@ -9,6 +9,7 @@ allowed:
|
|||||||
- mit
|
- mit
|
||||||
- cc0-1.0
|
- cc0-1.0
|
||||||
- unlicense
|
- unlicense
|
||||||
|
- 0bsd
|
||||||
|
|
||||||
reviewed:
|
reviewed:
|
||||||
npm:
|
npm:
|
||||||
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
@@ -0,0 +1,7 @@
|
|||||||
|
# Ignore list
|
||||||
|
/*
|
||||||
|
|
||||||
|
# Do not ignore these folders:
|
||||||
|
!__tests__/
|
||||||
|
!.github/
|
||||||
|
!src/
|
||||||
@@ -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'
|
||||||
|
};
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 80,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"useTabs": false,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "none",
|
|
||||||
"bracketSpacing": false,
|
|
||||||
"arrowParens": "avoid",
|
|
||||||
"parser": "typescript"
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to make participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all project spaces, and it also applies when
|
||||||
|
an individual is representing the project or its community in public spaces.
|
||||||
|
Examples of representing a project or community include using an official
|
||||||
|
project e-mail address, posting via an official social media account, or acting
|
||||||
|
as an appointed representative at an online or offline event. Representation of
|
||||||
|
a project may be further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at opensource+actions/setup-python@github.com. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
||||||
@@ -1,256 +1,108 @@
|
|||||||
# setup-python V2
|
# setup-python
|
||||||
|
|
||||||
<p align="left">
|
[](https://github.com/actions/setup-python/actions/workflows/basic-validation.yml)
|
||||||
<a href="https://github.com/actions/setup-python"><img alt="GitHub Actions status" src="https://github.com/actions/setup-python/workflows/Main%20workflow/badge.svg"></a>
|
[](https://github.com/actions/setup-python/actions/workflows/test-python.yml)
|
||||||
</p>
|
[](https://github.com/actions/setup-python/actions/workflows/test-pypy.yml)
|
||||||
|
[](https://github.com/actions/setup-python/actions/workflows/e2e-cache.yml)
|
||||||
|
|
||||||
This action sets up a Python environment for use in actions by:
|
This action provides the following functionality for GitHub Actions users:
|
||||||
|
|
||||||
- optionally installing and adding to PATH a version of Python that is already installed in the tools cache.
|
- Installing a version of Python or PyPy and (by default) adding it to the PATH
|
||||||
- downloading, installing and adding to PATH an available version of Python from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)) if a specific version is not available in the tools cache.
|
- Optionally caching dependencies for pip, pipenv and poetry
|
||||||
- failing if a specific version of Python is not preinstalled or available for download.
|
- Registering problem matchers for error output
|
||||||
- registering problem matchers for error output.
|
|
||||||
|
|
||||||
# What's new
|
## Basic usage
|
||||||
|
|
||||||
- Ability to download, install and set up Python packages from `actions/python-versions` that do not come preinstalled on runners.
|
|
||||||
- Allows for pinning to a specific patch version of Python without the worry of it ever being removed or changed.
|
|
||||||
- Automatic setup and download of Python packages if using a self-hosted runner.
|
|
||||||
- Support for pre-release versions of Python.
|
|
||||||
- Support for installing any version of PyPy on-flight
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
See [action.yml](action.yml)
|
See [action.yml](action.yml)
|
||||||
|
|
||||||
Basic:
|
**Python**
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
python-version: '3.10'
|
||||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
|
||||||
- run: python my_script.py
|
- run: python my_script.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Matrix Testing:
|
**PyPy**
|
||||||
```yaml
|
```yaml
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python-version: [ '2.x', '3.x', 'pypy-2.7', 'pypy-3.6', 'pypy-3.7' ]
|
|
||||||
name: Python ${{ matrix.python-version }} sample
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Setup python
|
- uses: actions/setup-python@v5
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: 'pypy3.9'
|
||||||
architecture: x64
|
|
||||||
- run: python my_script.py
|
- run: python my_script.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Exclude a specific Python version:
|
**GraalPy**
|
||||||
```yaml
|
```yaml
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
||||||
python-version: [2.7, 3.6, 3.7, 3.8, pypy-2.7, pypy-3.6]
|
|
||||||
exclude:
|
|
||||||
- os: macos-latest
|
|
||||||
python-version: 3.8
|
|
||||||
- os: windows-latest
|
|
||||||
python-version: 3.6
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python
|
- uses: actions/setup-python@v5
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: 'graalpy-22.3'
|
||||||
- name: Display Python version
|
|
||||||
run: python -c "import sys; print(sys.version)"
|
|
||||||
```
|
|
||||||
|
|
||||||
Download and set up a version of Python that does not come preinstalled on an image:
|
|
||||||
```yaml
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
# in this example, there is a newer version already installed, 3.7.7, so the older version will be downloaded
|
|
||||||
python-version: [3.5, 3.6, 3.7.4, 3.8]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python-version }}
|
|
||||||
- run: python my_script.py
|
- run: python my_script.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Download and set up an accurate pre-release version of Python:
|
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.
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.9.0-beta.4'
|
|
||||||
- run: python my_script.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Download and set up the latest available version of Python (includes both pre-release and stable versions):
|
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/).
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.9.0-alpha - 3.9.0' # SemVer's version range syntax
|
|
||||||
- run: python my_script.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Download and set up 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).
|
||||||
|
|
||||||
|
## Supported version syntax
|
||||||
|
|
||||||
|
The `python-version` input supports the [Semantic Versioning Specification](https://semver.org/) and some special version notations (e.g. `semver ranges`, `x.y-dev syntax`, etc.), for detailed examples please refer to the section: [Using python-version input](docs/advanced-usage.md#using-the-python-version-input) of the [Advanced usage](docs/advanced-usage.md) guide.
|
||||||
|
|
||||||
|
## Supported architectures
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
**Caching pip dependencies:**
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python-version:
|
|
||||||
- pypy-3.6 # the latest available version of PyPy that supports Python 3.6
|
|
||||||
- pypy-3.7 # the latest available version of PyPy that supports Python 3.7
|
|
||||||
- pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: '3.9'
|
||||||
- run: python my_script.py
|
cache: 'pip' # caching pip dependencies
|
||||||
|
- run: pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
More details on PyPy syntax and examples of using preview / nightly versions of PyPy can be found in the [Available versions of PyPy](#available-versions-of-pypy) section.
|
>**Note:** Restored cache will not be used if the requirements.txt file is not updated for a long time and a newer version of the dependency is available which can lead to an increase in total build time.
|
||||||
|
|
||||||
# Getting started with Python + Actions
|
>The requirements file format allows for specifying dependency versions using logical operators (for example chardet>=3.0.4) or specifying dependencies without any versions. In this case the pip install -r requirements.txt command will always try to install the latest available package version. To be sure that the cache will be used, please stick to a specific dependency version and update it manually if necessary.
|
||||||
|
|
||||||
Check out our detailed guide on using [Python with GitHub Actions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-python-with-github-actions).
|
See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poetry` in the section: [Caching packages](docs/advanced-usage.md#caching-packages) of the [Advanced usage](docs/advanced-usage.md) guide.
|
||||||
|
|
||||||
# Available versions of Python
|
## Advanced usage
|
||||||
|
|
||||||
`setup-python` is able to configure Python from two sources:
|
- [Using the python-version input](docs/advanced-usage.md#using-the-python-version-input)
|
||||||
|
- [Using the python-version-file input](docs/advanced-usage.md#using-the-python-version-file-input)
|
||||||
|
- [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)
|
||||||
|
- [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)
|
||||||
|
|
||||||
- Preinstalled versions of Python in the tools cache on GitHub-hosted runners.
|
## License
|
||||||
- For detailed information regarding the available versions of Python that are installed see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
|
|
||||||
- For every minor 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 tools cache.
|
|
||||||
- If the exact patch version doesn't matter to you, specifying just the major and minor version 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.
|
|
||||||
- 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
|
|
||||||
|
|
||||||
# Available versions of PyPy
|
|
||||||
|
|
||||||
`setup-python` is able to configure PyPy from two sources:
|
|
||||||
|
|
||||||
- Preinstalled versions of PyPy in the tools cache on GitHub-hosted runners
|
|
||||||
- For detailed information regarding the available versions of PyPy that are installed see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
|
|
||||||
- For the latest PyPy release, all versions of Python are cached.
|
|
||||||
- Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy-3.6`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy-3.6-v7.3.3`.
|
|
||||||
|
|
||||||
- Downloadable PyPy versions from the [official PyPy site](https://downloads.python.org/pypy/).
|
|
||||||
- All available versions that we can download are listed in [versions.json](https://downloads.python.org/pypy/versions.json) file.
|
|
||||||
- PyPy < 7.3.3 are not available to install on-flight.
|
|
||||||
- If some versions are not available, you can open an issue in https://foss.heptapod.net/pypy/pypy/
|
|
||||||
|
|
||||||
# Hosted Tool Cache
|
|
||||||
|
|
||||||
GitHub hosted runners have a tools cache that comes with a few versions of Python + PyPy already installed. This tools cache helps speed up runs and tool setup by not requiring any new downloads. There is an environment variable called `RUNNER_TOOL_CACHE` on each runner that describes the location of this tools cache and there is where you will find Python and PyPy installed. `setup-python` works by taking a specific version of Python or PyPy in this tools cache and adding it to PATH.
|
|
||||||
|
|
||||||
|| Location |
|
|
||||||
|------|-------|
|
|
||||||
|**Tool Cache Directory** |`RUNNER_TOOL_CACHE`|
|
|
||||||
|**Python Tool Cache**|`RUNNER_TOOL_CACHE/Python/*`|
|
|
||||||
|**PyPy Tool Cache**|`RUNNER_TOOL_CACHE/PyPy/*`|
|
|
||||||
|
|
||||||
GitHub virtual environments are setup in [actions/virtual-environments](https://github.com/actions/virtual-environments). During the setup, the available versions of Python and PyPy are automatically downloaded, setup and documented.
|
|
||||||
- [Tools cache setup for Ubuntu](https://github.com/actions/virtual-environments/blob/main/images/linux/scripts/installers/hosted-tool-cache.sh)
|
|
||||||
- [Tools cache setup for Windows](https://github.com/actions/virtual-environments/blob/main/images/win/scripts/Installers/Download-ToolCache.ps1)
|
|
||||||
|
|
||||||
# Specifying a Python version
|
|
||||||
|
|
||||||
If there is a specific version of Python that you need and you don't want to worry about any potential breaking changes due to patch updates (going from `3.7.5` to `3.7.6` for example), you should specify the exact major, minor, and patch version (such as `3.7.5`)
|
|
||||||
- The only downside to this is that set up will take a little longer since the exact version will have to be downloaded if the exact version is not already installed on the runner due to more recent versions.
|
|
||||||
- MSI installers are used on Windows for this, so runs will take a little longer to set up vs Mac and Linux.
|
|
||||||
|
|
||||||
You should specify only a major and minor version if you are okay with the most recent patch version being used.
|
|
||||||
- There will be a single patch version already installed on each runner for every minor version of Python that is supported.
|
|
||||||
- The patch version that will be preinstalled, will generally be the latest and every time there is a new patch released, the older version that is preinstalled will be replaced.
|
|
||||||
- Using the most recent patch version will result in a very quick setup since no downloads will be required since a locally installed version Python on the runner will be used.
|
|
||||||
|
|
||||||
# Specifying a PyPy version
|
|
||||||
The version of PyPy should be specified in the format `pypy-<python_version>[-v<pypy_version>]`.
|
|
||||||
The `<pypy_version>` parameter is optional and can be skipped. The latest version will be used in this case.
|
|
||||||
|
|
||||||
```
|
|
||||||
pypy-3.6 # the latest available version of PyPy that supports Python 3.6
|
|
||||||
pypy-3.7 # the latest available version of PyPy that supports Python 3.7
|
|
||||||
pypy-2.7 # the latest available version of PyPy that supports Python 2.7
|
|
||||||
pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3
|
|
||||||
pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x
|
|
||||||
pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy
|
|
||||||
pypy-3.7-nightly # Python 3.7 and nightly PyPy
|
|
||||||
```
|
|
||||||
|
|
||||||
# Using `setup-python` with a self hosted runner
|
|
||||||
|
|
||||||
Python distributions are only available for the same [environments](https://github.com/actions/virtual-environments#available-environments) that GitHub Actions hosted environments are available for. If you are using an unsupported version of Ubuntu such as `19.04` or another Linux distribution such as Fedora, `setup-python` will not work. If you have a supported self-hosted runner and you would like to use `setup-python`, there are a few extra things you need to make sure are set up so that new versions of Python can be downloaded and configured on your runner.
|
|
||||||
|
|
||||||
If you are experiencing problems while configuring Python on your self-hosted runner, turn on [step debugging](https://github.com/actions/toolkit/blob/main/docs/action-debugging.md#step-debug-logs) to see addition logs.
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
- Your runner needs to be running with administrator privileges so that the appropriate directories and files can be set up when downloading and installing a new version of Python for the first time.
|
|
||||||
- If your runner is configured as a service, make sure the account that is running the service has the appropriate write permissions so that Python can get installed. The default `NT AUTHORITY\NETWORK SERVICE` should be sufficient.
|
|
||||||
- You need `7zip` installed and added to your `PATH` so that the downloaded versions of Python files can be extracted properly during first-time setup.
|
|
||||||
- MSI installers are used when setting up Python on Windows. A word of caution as MSI installers update registry settings.
|
|
||||||
- The 3.8 MSI installer for Windows will not let you install another 3.8 version of Python. If `setup-python` fails for a 3.8 version of Python, make sure any previously installed versions are removed by going to "Apps & Features" in the Settings app.
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
|
|
||||||
- The Python packages that are downloaded from `actions/python-versions` are originally compiled from source in `/opt/hostedtoolcache/` with the [--enable-shared](https://github.com/actions/python-versions/blob/94f04ae6806c6633c82db94c6406a16e17decd5c/builders/ubuntu-python-builder.psm1#L35) flag, which makes them non-relocatable.
|
|
||||||
- Create an environment variable called `AGENT_TOOLSDIRECTORY` and set it to `/opt/hostedtoolcache`. This controls where the runner downloads and installs tools.
|
|
||||||
- In the same shell that your runner is using, type `export AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache`.
|
|
||||||
- A more permanent way of setting the environment variable is to create a `.env` file in the same directory as your runner and to add `AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache`. This ensures the variable is always set if your runner is configured as a service.
|
|
||||||
- Create a directory called `hostedtoolcache` inside `/opt`.
|
|
||||||
- The user starting the runner must have write permission to the `/opt/hostedtoolcache` directory. It is not possible to start the Linux runner with `sudo` and the `/opt` directory usually requires root privileges to write to. Check the current user and group that the runner belongs to by typing `ls -l` inside the runners root directory.
|
|
||||||
- The runner can be granted write access to the `/opt/hostedtoolcache` directory using a few techniques:
|
|
||||||
- The user starting the runner is the owner, and the owner has write permission.
|
|
||||||
- The user starting the runner is in the owning group, and the owning group has write permission.
|
|
||||||
- All users have write permission.
|
|
||||||
- One quick way to grant access is to change the user and group of `/opt/hostedtoolcache` to be the same as the runners using `chown`.
|
|
||||||
- `sudo chown runner-user:runner-group opt/hostedtoolcache/`.
|
|
||||||
- If your runner is configured as a service and you run into problems, make sure the user that the service is running as is correct. For more information, you can [check the status of your self-hosted runner](https://help.github.com/en/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service#checking-the-status-of-the-service).
|
|
||||||
|
|
||||||
### Mac
|
|
||||||
|
|
||||||
- The same setup that applies to `Linux` also applies to `Mac`, just with a different tools cache directory.
|
|
||||||
- Create a directory called `/Users/runner/hostedtoolcache`.
|
|
||||||
- Set the `AGENT_TOOLSDIRECTORY` environment variable to `/Users/runner/hostedtoolcache`.
|
|
||||||
- Change the permissions of `/Users/runner/hostedtoolcache` so that the runner has write access.
|
|
||||||
|
|
||||||
|
|
||||||
# Using Python without `setup-python`
|
|
||||||
|
|
||||||
`setup-python` helps keep your dependencies explicit and ensures consistent behavior between different runners. If you use `python` in a shell on a GitHub hosted runner without `setup-python` it will default to whatever is in PATH. The default version of Python in PATH vary between runners and can change unexpectedly so we recommend you always use `setup-python`.
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
The scripts and documentation in this project are released under the [MIT License](LICENSE).
|
The scripts and documentation in this project are released under the [MIT License](LICENSE).
|
||||||
|
|
||||||
# Contributions
|
## Contributions
|
||||||
|
|
||||||
Contributions are welcome! See our [Contributor's Guide](docs/contributors.md).
|
Contributions are welcome! See our [Contributor's Guide](docs/contributors.md).
|
||||||
|
|||||||
@@ -0,0 +1,348 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
describe('restore-cache', () => {
|
||||||
|
const pipFileLockHash =
|
||||||
|
'f8428d7cf00ea53a5c3702f0a9cb3cc467f76cd86a34723009350c4e4b32751a';
|
||||||
|
const requirementsHash =
|
||||||
|
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
|
||||||
|
const requirementsLinuxHash =
|
||||||
|
'2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c';
|
||||||
|
const poetryLockHash =
|
||||||
|
'f24ea1ad73968e6c8d80c16a093ade72d9332c433aeef979a0dd943e6a99b2ab';
|
||||||
|
const poetryConfigOutput = `
|
||||||
|
cache-dir = "/Users/patrick/Library/Caches/pypoetry"
|
||||||
|
experimental.new-installer = false
|
||||||
|
installer.parallel = true
|
||||||
|
virtualenvs.create = true
|
||||||
|
virtualenvs.in-project = true
|
||||||
|
virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/pypoetry/virtualenvs
|
||||||
|
`;
|
||||||
|
|
||||||
|
// core spy
|
||||||
|
let infoSpy: jest.SpyInstance;
|
||||||
|
let warningSpy: jest.SpyInstance;
|
||||||
|
let debugSpy: jest.SpyInstance;
|
||||||
|
let saveStateSpy: jest.SpyInstance;
|
||||||
|
let getStateSpy: jest.SpyInstance;
|
||||||
|
let setOutputSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
// cache spy
|
||||||
|
let restoreCacheSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
// exec spy
|
||||||
|
let getExecOutputSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
// io spy
|
||||||
|
let whichSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env['RUNNER_OS'] = process.env['RUNNER_OS'] ?? 'linux';
|
||||||
|
|
||||||
|
infoSpy = jest.spyOn(core, 'info');
|
||||||
|
infoSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
warningSpy = jest.spyOn(core, 'warning');
|
||||||
|
warningSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
debugSpy = jest.spyOn(core, 'debug');
|
||||||
|
debugSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
saveStateSpy = jest.spyOn(core, 'saveState');
|
||||||
|
saveStateSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
getStateSpy = jest.spyOn(core, 'getState');
|
||||||
|
getStateSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
||||||
|
getExecOutputSpy.mockImplementation((input: string) => {
|
||||||
|
if (input.includes('pip')) {
|
||||||
|
return {stdout: 'pip', stderr: '', exitCode: 0};
|
||||||
|
}
|
||||||
|
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};
|
||||||
|
});
|
||||||
|
|
||||||
|
setOutputSpy = jest.spyOn(core, 'setOutput');
|
||||||
|
setOutputSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
|
||||||
|
restoreCacheSpy.mockImplementation(
|
||||||
|
(cachePaths: string[], primaryKey: string, restoreKey?: string) => {
|
||||||
|
return primaryKey;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
whichSpy = jest.spyOn(io, 'which');
|
||||||
|
whichSpy.mockImplementation(() => '/path/to/python');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Validate provided package manager', () => {
|
||||||
|
it.each(['npm', 'pip2', 'pip21', 'pip21.3', 'pipenv32'])(
|
||||||
|
'Throw an error because %s is not supported',
|
||||||
|
async packageManager => {
|
||||||
|
expect(() =>
|
||||||
|
getCacheDistributor(packageManager, '3.8.12', undefined)
|
||||||
|
).toThrow(`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',
|
||||||
|
'__tests__/data/requirements-linux.txt',
|
||||||
|
requirementsLinuxHash,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'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')
|
||||||
|
]
|
||||||
|
]
|
||||||
|
])(
|
||||||
|
'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 : '';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const cacheDistributor = getCacheDistributor(
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile
|
||||||
|
);
|
||||||
|
|
||||||
|
await cacheDistributor.restoreCache();
|
||||||
|
|
||||||
|
if (cachePaths !== undefined) {
|
||||||
|
expect(saveStateSpy).toHaveBeenCalledWith(
|
||||||
|
State.CACHE_PATHS,
|
||||||
|
cachePaths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.platform === 'linux' && packageManager === 'pip') {
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(
|
||||||
|
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-20.04-Ubuntu-python-${pythonVersion}-${packageManager}-${fileHash}`
|
||||||
|
);
|
||||||
|
} else if (packageManager === 'poetry') {
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(
|
||||||
|
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-v2-${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']])(
|
||||||
|
'Should throw an error because dependency file is not found',
|
||||||
|
async (
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile,
|
||||||
|
cacheDependencyPath
|
||||||
|
) => {
|
||||||
|
const cacheDistributor = getCacheDistributor(
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile
|
||||||
|
);
|
||||||
|
|
||||||
|
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', () => {
|
||||||
|
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',
|
||||||
|
'__tests__/data/requirements-linux.txt',
|
||||||
|
pipFileLockHash
|
||||||
|
],
|
||||||
|
['pip', '3.8.12', '__tests__/data/requirements.txt', pipFileLockHash],
|
||||||
|
['pipenv', '3.9.1', '__tests__/data/**/Pipfile.lock', requirementsHash],
|
||||||
|
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
|
||||||
|
['poetry', '3.9.1', '__tests__/data/**/poetry.lock', requirementsHash]
|
||||||
|
])(
|
||||||
|
'restored dependencies for %s by primaryKey',
|
||||||
|
async (packageManager, pythonVersion, dependencyFile, fileHash) => {
|
||||||
|
restoreCacheSpy.mockImplementation(
|
||||||
|
(cachePaths: string[], primaryKey: string, restoreKey?: string) => {
|
||||||
|
return primaryKey !== fileHash && restoreKey ? pipFileLockHash : '';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const cacheDistributor = getCacheDistributor(
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile
|
||||||
|
);
|
||||||
|
await cacheDistributor.restoreCache();
|
||||||
|
let result = '';
|
||||||
|
|
||||||
|
switch (packageManager) {
|
||||||
|
case 'pip':
|
||||||
|
result = `Cache restored from key: ${fileHash}`;
|
||||||
|
break;
|
||||||
|
case 'pipenv':
|
||||||
|
result = 'pipenv cache is not found';
|
||||||
|
break;
|
||||||
|
case 'poetry':
|
||||||
|
result = 'poetry cache is not found';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(result);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Check if handleMatchResult', () => {
|
||||||
|
it.each([
|
||||||
|
['pip', '3.8.12', 'requirements.txt', 'someKey', 'someKey', true],
|
||||||
|
['pipenv', '3.9.1', 'requirements.txt', 'someKey', 'someKey', true],
|
||||||
|
['poetry', '3.8.12', 'requirements.txt', 'someKey', 'someKey', true],
|
||||||
|
['pip', '3.9.2', 'requirements.txt', undefined, 'someKey', false],
|
||||||
|
['pipenv', '3.8.12', 'requirements.txt', undefined, 'someKey', false],
|
||||||
|
['poetry', '3.9.12', 'requirements.txt', undefined, 'someKey', false]
|
||||||
|
])(
|
||||||
|
'sets correct outputs',
|
||||||
|
async (
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile,
|
||||||
|
matchedKey,
|
||||||
|
restoredKey,
|
||||||
|
expectedOutputValue
|
||||||
|
) => {
|
||||||
|
const cacheDistributor = getCacheDistributor(
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile
|
||||||
|
);
|
||||||
|
cacheDistributor.handleMatchResult(matchedKey, restoredKey);
|
||||||
|
expect(setOutputSpy).toHaveBeenCalledWith(
|
||||||
|
'cache-hit',
|
||||||
|
expectedOutputValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import * as cache from '@actions/cache';
|
||||||
|
import * as exec from '@actions/exec';
|
||||||
|
import {run} from '../src/cache-save';
|
||||||
|
import {State} from '../src/cache-distributions/cache-distributor';
|
||||||
|
|
||||||
|
describe('run', () => {
|
||||||
|
const pipFileLockHash =
|
||||||
|
'd1dd6218299d8a6db5fc2001d988b34a8b31f1e9d0bb4534d377dde7c19f64b3';
|
||||||
|
const requirementsHash =
|
||||||
|
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
|
||||||
|
const requirementsLinuxHash =
|
||||||
|
'2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c';
|
||||||
|
const poetryLockHash =
|
||||||
|
'571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836';
|
||||||
|
|
||||||
|
// core spy
|
||||||
|
let infoSpy: jest.SpyInstance;
|
||||||
|
let warningSpy: jest.SpyInstance;
|
||||||
|
let debugSpy: jest.SpyInstance;
|
||||||
|
let saveStateSpy: jest.SpyInstance;
|
||||||
|
let getStateSpy: jest.SpyInstance;
|
||||||
|
let getInputSpy: jest.SpyInstance;
|
||||||
|
let setFailedSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
// cache spy
|
||||||
|
let saveCacheSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
// exec spy
|
||||||
|
let getExecOutputSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
let inputs = {} as any;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env['RUNNER_OS'] = process.env['RUNNER_OS'] ?? 'linux';
|
||||||
|
|
||||||
|
infoSpy = jest.spyOn(core, 'info');
|
||||||
|
infoSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
warningSpy = jest.spyOn(core, 'warning');
|
||||||
|
warningSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
debugSpy = jest.spyOn(core, 'debug');
|
||||||
|
debugSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
saveStateSpy = jest.spyOn(core, 'saveState');
|
||||||
|
saveStateSpy.mockImplementation(input => undefined);
|
||||||
|
|
||||||
|
getStateSpy = jest.spyOn(core, 'getState');
|
||||||
|
getStateSpy.mockImplementation(input => {
|
||||||
|
if (input === State.CACHE_PATHS) {
|
||||||
|
return JSON.stringify([__dirname]);
|
||||||
|
}
|
||||||
|
return requirementsHash;
|
||||||
|
});
|
||||||
|
|
||||||
|
setFailedSpy = jest.spyOn(core, 'setFailed');
|
||||||
|
|
||||||
|
getInputSpy = jest.spyOn(core, 'getInput');
|
||||||
|
getInputSpy.mockImplementation(input => inputs[input]);
|
||||||
|
|
||||||
|
getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
||||||
|
getExecOutputSpy.mockImplementation((input: string) => {
|
||||||
|
if (input.includes('pip')) {
|
||||||
|
return {stdout: 'pip', stderr: '', exitCode: 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {stdout: '', stderr: 'Error occured', exitCode: 2};
|
||||||
|
});
|
||||||
|
|
||||||
|
saveCacheSpy = jest.spyOn(cache, 'saveCache');
|
||||||
|
saveCacheSpy.mockImplementation(() => undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Package manager validation', () => {
|
||||||
|
it('Package manager is not provided, skip caching', async () => {
|
||||||
|
inputs['cache'] = '';
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(getInputSpy).toHaveBeenCalled();
|
||||||
|
expect(infoSpy).not.toHaveBeenCalled();
|
||||||
|
expect(saveCacheSpy).not.toHaveBeenCalled();
|
||||||
|
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else if (name === State.CACHE_PATHS) {
|
||||||
|
return JSON.stringify([__dirname]);
|
||||||
|
} else {
|
||||||
|
return pipFileLockHash;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(getInputSpy).toHaveBeenCalled();
|
||||||
|
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||||
|
expect(infoSpy).not.toHaveBeenCalledWith(
|
||||||
|
`Cache hit occurred on the primary key ${requirementsHash}, not saving cache.`
|
||||||
|
);
|
||||||
|
expect(saveCacheSpy).toHaveBeenCalled();
|
||||||
|
expect(infoSpy).toHaveBeenLastCalledWith(
|
||||||
|
`Cache saved with the key: ${pipFileLockHash}`
|
||||||
|
);
|
||||||
|
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else if (name === State.CACHE_PATHS) {
|
||||||
|
return JSON.stringify([__dirname]);
|
||||||
|
} else {
|
||||||
|
return requirementsHash;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(getInputSpy).toHaveBeenCalled();
|
||||||
|
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||||
|
expect(infoSpy).not.toHaveBeenCalledWith(
|
||||||
|
`Cache hit occurred on the primary key ${pipFileLockHash}, not saving cache.`
|
||||||
|
);
|
||||||
|
expect(saveCacheSpy).toHaveBeenCalled();
|
||||||
|
expect(infoSpy).toHaveBeenLastCalledWith(
|
||||||
|
`Cache saved with the key: ${requirementsHash}`
|
||||||
|
);
|
||||||
|
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else if (name === State.CACHE_PATHS) {
|
||||||
|
return JSON.stringify([__dirname]);
|
||||||
|
} else {
|
||||||
|
return requirementsHash;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(getInputSpy).toHaveBeenCalled();
|
||||||
|
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||||
|
expect(infoSpy).not.toHaveBeenCalledWith(
|
||||||
|
`Cache hit occurred on the primary key ${poetryLockHash}, not saving cache.`
|
||||||
|
);
|
||||||
|
expect(saveCacheSpy).toHaveBeenCalled();
|
||||||
|
expect(infoSpy).toHaveBeenLastCalledWith(
|
||||||
|
`Cache saved with the key: ${requirementsHash}`
|
||||||
|
);
|
||||||
|
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else if (name === State.CACHE_PATHS) {
|
||||||
|
return JSON.stringify([__dirname]);
|
||||||
|
} else {
|
||||||
|
return requirementsHash;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
saveCacheSpy.mockImplementation(() => {
|
||||||
|
return -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(getInputSpy).toHaveBeenCalled();
|
||||||
|
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||||
|
expect(infoSpy).not.toHaveBeenCalled();
|
||||||
|
expect(saveCacheSpy).toHaveBeenCalled();
|
||||||
|
expect(infoSpy).not.toHaveBeenLastCalledWith(
|
||||||
|
`Cache saved with the key: ${poetryLockHash}`
|
||||||
|
);
|
||||||
|
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else if (name === State.CACHE_PATHS) {
|
||||||
|
return JSON.stringify([__dirname]);
|
||||||
|
} else {
|
||||||
|
return requirementsHash;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
saveCacheSpy.mockImplementation(() => {
|
||||||
|
throw new cache.ValidationError('Validation failed');
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(getInputSpy).toHaveBeenCalled();
|
||||||
|
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||||
|
expect(infoSpy).not.toHaveBeenCalledWith();
|
||||||
|
expect(saveCacheSpy).toHaveBeenCalled();
|
||||||
|
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
inputs = {};
|
||||||
|
});
|
||||||
|
});
|
||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PYTHON_PATH="$1"
|
||||||
|
PATH_EXECUTABLE=$(python -c 'import sys; print(sys.executable)')
|
||||||
|
PYTHON_PATH_EXECUTABLE=$("${PYTHON_PATH}" -c 'import sys; print(sys.executable)')
|
||||||
|
if [ "${PATH_EXECUTABLE}" != "${PYTHON_PATH_EXECUTABLE}" ]; then
|
||||||
|
echo "Executable mismatch."
|
||||||
|
echo "python in PATH is: ${PATH_EXECUTABLE}"
|
||||||
|
echo "python-path (${PYTHON_PATH}) is: ${PYTHON_PATH_EXECUTABLE}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "python-path: ${PYTHON_PATH}"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[[source]]
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
name = "pypi"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
flake8 = "==6.0.0"
|
||||||
|
numpy = "==1.25.1"
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "*"
|
||||||
Generated
+84
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"hash": {
|
||||||
|
"sha256": "dcea65dabfe8442466b5e9280ecab72cfa7bf555791ee0ad55b6e7255dca1f43"
|
||||||
|
},
|
||||||
|
"pipfile-spec": 6,
|
||||||
|
"requires": {
|
||||||
|
"python_version": "*"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"name": "pypi",
|
||||||
|
"url": "https://pypi.org/simple",
|
||||||
|
"verify_ssl": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"flake8": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7",
|
||||||
|
"sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==6.0.0"
|
||||||
|
},
|
||||||
|
"mccabe": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
|
||||||
|
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.6'",
|
||||||
|
"version": "==0.7.0"
|
||||||
|
},
|
||||||
|
"numpy": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:012097b5b0d00a11070e8f2e261128c44157a8689f7dedcf35576e525893f4fe",
|
||||||
|
"sha256:0d3fe3dd0506a28493d82dc3cf254be8cd0d26f4008a417385cbf1ae95b54004",
|
||||||
|
"sha256:0def91f8af6ec4bb94c370e38c575855bf1d0be8a8fbfba42ef9c073faf2cf19",
|
||||||
|
"sha256:1a180429394f81c7933634ae49b37b472d343cccb5bb0c4a575ac8bbc433722f",
|
||||||
|
"sha256:1d5d3c68e443c90b38fdf8ef40e60e2538a27548b39b12b73132456847f4b631",
|
||||||
|
"sha256:20e1266411120a4f16fad8efa8e0454d21d00b8c7cee5b5ccad7565d95eb42dd",
|
||||||
|
"sha256:247d3ffdd7775bdf191f848be8d49100495114c82c2bd134e8d5d075fb386a1c",
|
||||||
|
"sha256:35a9527c977b924042170a0887de727cd84ff179e478481404c5dc66b4170009",
|
||||||
|
"sha256:38eb6548bb91c421261b4805dc44def9ca1a6eef6444ce35ad1669c0f1a3fc5d",
|
||||||
|
"sha256:3d7abcdd85aea3e6cdddb59af2350c7ab1ed764397f8eec97a038ad244d2d105",
|
||||||
|
"sha256:41a56b70e8139884eccb2f733c2f7378af06c82304959e174f8e7370af112e09",
|
||||||
|
"sha256:4a90725800caeaa160732d6b31f3f843ebd45d6b5f3eec9e8cc287e30f2805bf",
|
||||||
|
"sha256:6b82655dd8efeea69dbf85d00fca40013d7f503212bc5259056244961268b66e",
|
||||||
|
"sha256:6c6c9261d21e617c6dc5eacba35cb68ec36bb72adcff0dee63f8fbc899362588",
|
||||||
|
"sha256:77d339465dff3eb33c701430bcb9c325b60354698340229e1dff97745e6b3efa",
|
||||||
|
"sha256:791f409064d0a69dd20579345d852c59822c6aa087f23b07b1b4e28ff5880fcb",
|
||||||
|
"sha256:9a3a9f3a61480cc086117b426a8bd86869c213fc4072e606f01c4e4b66eb92bf",
|
||||||
|
"sha256:c1516db588987450b85595586605742879e50dcce923e8973f79529651545b57",
|
||||||
|
"sha256:c40571fe966393b212689aa17e32ed905924120737194b5d5c1b20b9ed0fb171",
|
||||||
|
"sha256:d412c1697c3853c6fc3cb9751b4915859c7afe6a277c2bf00acf287d56c4e625",
|
||||||
|
"sha256:d5154b1a25ec796b1aee12ac1b22f414f94752c5f94832f14d8d6c9ac40bcca6",
|
||||||
|
"sha256:d736b75c3f2cb96843a5c7f8d8ccc414768d34b0a75f466c05f3a739b406f10b",
|
||||||
|
"sha256:e8f6049c4878cb16960fbbfb22105e49d13d752d4d8371b55110941fb3b17800",
|
||||||
|
"sha256:f76aebc3358ade9eacf9bc2bb8ae589863a4f911611694103af05346637df1b7",
|
||||||
|
"sha256:fd67b306320dcadea700a8f79b9e671e607f8696e98ec255915c0c6d6b818503"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.25.1"
|
||||||
|
},
|
||||||
|
"pycodestyle": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053",
|
||||||
|
"sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.6'",
|
||||||
|
"version": "==2.10.0"
|
||||||
|
},
|
||||||
|
"pyflakes": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf",
|
||||||
|
"sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.6'",
|
||||||
|
"version": "==3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"develop": {}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
+1
@@ -0,0 +1 @@
|
|||||||
|
../poetry.lock
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../pyproject.toml
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
numpy==1.22.3
|
||||||
|
flake8==6.0.0
|
||||||
Generated
+413
@@ -0,0 +1,413 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "altgraph"
|
||||||
|
version = "0.17.2"
|
||||||
|
description = "Python graph (network) package"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "certifi"
|
||||||
|
version = "2020.6.20"
|
||||||
|
description = "Python package for providing Mozilla's CA Bundle."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chardet"
|
||||||
|
version = "3.0.4"
|
||||||
|
description = "Universal encoding detector for Python 2 and 3"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
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]
|
||||||
|
docutils = "*"
|
||||||
|
Kivy-Garden = ">=0.1.4"
|
||||||
|
pygments = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
tuio = ["oscpy"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
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 = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
requests = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "packaging"
|
||||||
|
version = "21.0"
|
||||||
|
description = "Core utilities for Python packages"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
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 = "2021.9.3"
|
||||||
|
description = "Python PE parsing module"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6.0"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
future = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pillow"
|
||||||
|
version = "7.2.0"
|
||||||
|
description = "Python Imaging Library (Fork)"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pygments"
|
||||||
|
version = "2.6.1"
|
||||||
|
description = "Pygments is a syntax highlighting package written in Python."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyinstaller"
|
||||||
|
version = "3.6"
|
||||||
|
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
altgraph = "*"
|
||||||
|
dis3 = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyparsing"
|
||||||
|
version = "2.4.7"
|
||||||
|
description = "Python parsing module"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pywin32-ctypes"
|
||||||
|
version = "0.2.0"
|
||||||
|
description = ""
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "requests"
|
||||||
|
version = "2.24.0"
|
||||||
|
description = "Python HTTP for Humans."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
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]
|
||||||
|
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||||
|
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urllib3"
|
||||||
|
version = "1.25.9"
|
||||||
|
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
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 = "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"},
|
||||||
|
]
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "testactiontasks"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = ["Your Name <you@example.com>"]
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.8"
|
||||||
|
flake8 = "^4.0.1"
|
||||||
|
|
||||||
|
[tool.poetry.dev-dependencies]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
@@ -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",
|
"pypy_version": "7.3.3",
|
||||||
"python_version": "3.6.12",
|
"python_version": "3.6.12",
|
||||||
@@ -89,6 +179,45 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"pypy_version": "7.3.4rc1",
|
||||||
|
"python_version": "2.7.18",
|
||||||
|
"stable": false,
|
||||||
|
"latest_pypy": false,
|
||||||
|
"date": "2021-03-19",
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"filename": "pypy2.7-v7.3.4rc1-aarch64.tar.bz2",
|
||||||
|
"arch": "aarch64",
|
||||||
|
"platform": "linux",
|
||||||
|
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-aarch64.tar.bz2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "pypy2.7-v7.3.4rc1-linux32.tar.bz2",
|
||||||
|
"arch": "i686",
|
||||||
|
"platform": "linux",
|
||||||
|
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-linux32.tar.bz2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "pypy2.7-v7.3.4rc1-linux64.tar.bz2",
|
||||||
|
"arch": "x64",
|
||||||
|
"platform": "linux",
|
||||||
|
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-linux64.tar.bz2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "pypy2.7-v7.3.4rc1-osx64.tar.bz2",
|
||||||
|
"arch": "x64",
|
||||||
|
"platform": "darwin",
|
||||||
|
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-osx64.tar.bz2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "pypy2.7-v7.3.4rc1-win64.zip",
|
||||||
|
"arch": "x64",
|
||||||
|
"platform": "win64",
|
||||||
|
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-win64.zip"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"pypy_version": "7.3.3rc2",
|
"pypy_version": "7.3.3rc2",
|
||||||
"python_version": "3.7.7",
|
"python_version": "3.7.7",
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
certifi==2020.6.20
|
||||||
|
chardet==3.0.4
|
||||||
|
docutils==0.16
|
||||||
|
idna==2.10
|
||||||
|
Kivy==2.0.0rc3
|
||||||
|
Kivy-Garden==0.1.4
|
||||||
|
packaging==20.7
|
||||||
|
pdf2image==1.12.1
|
||||||
|
Pygments==2.6.1
|
||||||
|
requests==2.24.0
|
||||||
|
urllib3==1.25.10
|
||||||
|
xlrd==1.2.0
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
altgraph==0.17.2
|
||||||
|
|
||||||
|
certifi==2020.6.20
|
||||||
|
|
||||||
|
chardet==3.0.4
|
||||||
|
|
||||||
|
docutils==0.16
|
||||||
|
|
||||||
|
future==0.18.2; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'
|
||||||
|
|
||||||
|
idna==2.9
|
||||||
|
|
||||||
|
itsdangerous==1.1.0
|
||||||
|
|
||||||
|
kivy-deps-angle==0.3.0
|
||||||
|
|
||||||
|
kivy-deps.glew==0.1.12
|
||||||
|
|
||||||
|
kivy-deps.gstreamer==0.1.17
|
||||||
|
|
||||||
|
kivy-deps.sdl2==0.1.22
|
||||||
|
|
||||||
|
kivy-garden==0.1.4
|
||||||
|
|
||||||
|
kivy==1.11.1
|
||||||
|
|
||||||
|
packaging==21.0
|
||||||
|
|
||||||
|
pdf2image==1.12.1
|
||||||
|
|
||||||
|
pefile==2021.9.3; python_full_version >= '3.6.0'
|
||||||
|
|
||||||
|
pillow==7.2
|
||||||
|
|
||||||
|
pygments==2.6.1
|
||||||
|
|
||||||
|
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.24.0
|
||||||
|
|
||||||
|
urllib3==1.25.9
|
||||||
|
|
||||||
|
xlrd==1.2.0
|
||||||
@@ -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",
|
"version": "1.2.3",
|
||||||
"stable": true,
|
"stable": true,
|
||||||
@@ -25,27 +50,27 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"version": "1.2.3-beta.2",
|
"version": "1.1.0-beta.2",
|
||||||
"stable": false,
|
"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": [
|
"files": [
|
||||||
{
|
{
|
||||||
"filename": "sometool-1.2.3-linux-x64.tar.gz",
|
"filename": "sometool-1.1.0-linux-x64.tar.gz",
|
||||||
"arch": "x64",
|
"arch": "x64",
|
||||||
"platform": "linux",
|
"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",
|
"arch": "x64",
|
||||||
"platform": "darwin",
|
"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",
|
"arch": "x64",
|
||||||
"platform": "win32",
|
"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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,378 @@
|
|||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
+242
-15
@@ -2,9 +2,10 @@ import fs from 'fs';
|
|||||||
|
|
||||||
import * as utils from '../src/utils';
|
import * as utils from '../src/utils';
|
||||||
import {HttpClient} from '@actions/http-client';
|
import {HttpClient} from '@actions/http-client';
|
||||||
import * as ifm from '@actions/http-client/interfaces';
|
import * as ifm from '@actions/http-client/lib/interfaces';
|
||||||
import * as tc from '@actions/tool-cache';
|
import * as tc from '@actions/tool-cache';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
@@ -13,11 +14,10 @@ import * as finder from '../src/find-pypy';
|
|||||||
import {
|
import {
|
||||||
IPyPyManifestRelease,
|
IPyPyManifestRelease,
|
||||||
IS_WINDOWS,
|
IS_WINDOWS,
|
||||||
validateVersion,
|
|
||||||
getPyPyVersionFromPath
|
getPyPyVersionFromPath
|
||||||
} from '../src/utils';
|
} from '../src/utils';
|
||||||
|
|
||||||
const manifestData = require('./data/pypy.json');
|
import manifestData from './data/pypy.json';
|
||||||
|
|
||||||
let architecture: string;
|
let architecture: string;
|
||||||
|
|
||||||
@@ -37,16 +37,34 @@ describe('parsePyPyVersion', () => {
|
|||||||
['pypy-3.6-v7.x', {pythonVersion: '3.6', pypyVersion: 'v7.x'}],
|
['pypy-3.6-v7.x', {pythonVersion: '3.6', pypyVersion: 'v7.x'}],
|
||||||
['pypy-3.6', {pythonVersion: '3.6', pypyVersion: 'x'}],
|
['pypy-3.6', {pythonVersion: '3.6', pypyVersion: 'x'}],
|
||||||
['pypy-3.6-nightly', {pythonVersion: '3.6', pypyVersion: 'nightly'}],
|
['pypy-3.6-nightly', {pythonVersion: '3.6', pypyVersion: 'nightly'}],
|
||||||
['pypy-3.6-v7.3.3rc1', {pythonVersion: '3.6', pypyVersion: 'v7.3.3-rc.1'}]
|
['pypy-3.6-v7.3.3rc1', {pythonVersion: '3.6', pypyVersion: 'v7.3.3-rc.1'}],
|
||||||
|
['pypy3.8-v7.3.7', {pythonVersion: '3.8', pypyVersion: 'v7.3.7'}],
|
||||||
|
['pypy3.8-v7.3.x', {pythonVersion: '3.8', pypyVersion: 'v7.3.x'}],
|
||||||
|
['pypy3.8-v7.x', {pythonVersion: '3.8', pypyVersion: 'v7.x'}],
|
||||||
|
['pypy3.8', {pythonVersion: '3.8', pypyVersion: 'x'}],
|
||||||
|
['pypy3.9-nightly', {pythonVersion: '3.9', pypyVersion: 'nightly'}],
|
||||||
|
['pypy3.9-v7.3.8rc1', {pythonVersion: '3.9', pypyVersion: 'v7.3.8-rc.1'}]
|
||||||
])('%s -> %s', (input, expected) => {
|
])('%s -> %s', (input, expected) => {
|
||||||
expect(finder.parsePyPyVersion(input)).toEqual(expected);
|
expect(finder.parsePyPyVersion(input)).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw on invalid input', () => {
|
it.each(['', 'pypy-', 'pypy', 'p', 'notpypy-'])(
|
||||||
expect(() => finder.parsePyPyVersion('pypy-')).toThrowError(
|
'throw on invalid input "%s"',
|
||||||
"Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-<python-version>'. See README for examples and documentation."
|
input => {
|
||||||
|
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."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each(['pypy-2', 'pypy-3', 'pypy2', 'pypy3', 'pypy3.x', 'pypy3.8.10'])(
|
||||||
|
'throw on invalid input "%s"',
|
||||||
|
input => {
|
||||||
|
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."
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getPyPyVersionFromPath', () => {
|
describe('getPyPyVersionFromPath', () => {
|
||||||
@@ -63,6 +81,12 @@ describe('findPyPyToolCache', () => {
|
|||||||
const pypyPath = path.join('PyPy', actualPythonVersion, architecture);
|
const pypyPath = path.join('PyPy', actualPythonVersion, architecture);
|
||||||
let tcFind: jest.SpyInstance;
|
let tcFind: jest.SpyInstance;
|
||||||
let spyReadExactPyPyVersion: jest.SpyInstance;
|
let spyReadExactPyPyVersion: 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(() => {
|
beforeEach(() => {
|
||||||
tcFind = jest.spyOn(tc, 'find');
|
tcFind = jest.spyOn(tc, 'find');
|
||||||
@@ -75,6 +99,24 @@ describe('findPyPyToolCache', () => {
|
|||||||
|
|
||||||
spyReadExactPyPyVersion = jest.spyOn(utils, 'readExactPyPyVersionFile');
|
spyReadExactPyPyVersion = jest.spyOn(utils, 'readExactPyPyVersionFile');
|
||||||
spyReadExactPyPyVersion.mockImplementation(() => actualPyPyVersion);
|
spyReadExactPyPyVersion.mockImplementation(() => actualPyPyVersion);
|
||||||
|
|
||||||
|
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(() => {
|
afterEach(() => {
|
||||||
@@ -117,6 +159,13 @@ describe('findPyPyToolCache', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('findPyPyVersion', () => {
|
describe('findPyPyVersion', () => {
|
||||||
|
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 tcFind: jest.SpyInstance;
|
||||||
let spyExtractZip: jest.SpyInstance;
|
let spyExtractZip: jest.SpyInstance;
|
||||||
let spyExtractTar: jest.SpyInstance;
|
let spyExtractTar: jest.SpyInstance;
|
||||||
@@ -130,8 +179,34 @@ describe('findPyPyVersion', () => {
|
|||||||
let spyWriteExactPyPyVersionFile: jest.SpyInstance;
|
let spyWriteExactPyPyVersionFile: jest.SpyInstance;
|
||||||
let spyCacheDir: jest.SpyInstance;
|
let spyCacheDir: jest.SpyInstance;
|
||||||
let spyChmodSync: jest.SpyInstance;
|
let spyChmodSync: jest.SpyInstance;
|
||||||
|
let spyCoreAddPath: jest.SpyInstance;
|
||||||
|
let spyCoreExportVariable: jest.SpyInstance;
|
||||||
|
const env = process.env;
|
||||||
|
|
||||||
beforeEach(() => {
|
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 = jest.spyOn(tc, 'find');
|
||||||
tcFind.mockImplementation((tool: string, version: string) => {
|
tcFind.mockImplementation((tool: string, version: string) => {
|
||||||
const semverRange = new semver.Range(version);
|
const semverRange = new semver.Range(version);
|
||||||
@@ -165,7 +240,7 @@ describe('findPyPyVersion', () => {
|
|||||||
|
|
||||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||||
spyHttpClient.mockImplementation(
|
spyHttpClient.mockImplementation(
|
||||||
async (): Promise<ifm.ITypedResponse<IPyPyManifestRelease[]>> => {
|
async (): Promise<ifm.TypedResponse<IPyPyManifestRelease[]>> => {
|
||||||
const result = JSON.stringify(manifestData);
|
const result = JSON.stringify(manifestData);
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
@@ -183,32 +258,52 @@ describe('findPyPyVersion', () => {
|
|||||||
|
|
||||||
spyExistsSync = jest.spyOn(fs, 'existsSync');
|
spyExistsSync = jest.spyOn(fs, 'existsSync');
|
||||||
spyExistsSync.mockReturnValue(true);
|
spyExistsSync.mockReturnValue(true);
|
||||||
|
|
||||||
|
spyCoreAddPath = jest.spyOn(core, 'addPath');
|
||||||
|
|
||||||
|
spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
|
process.env = env;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('found PyPy in toolcache', async () => {
|
it('found PyPy in toolcache', async () => {
|
||||||
await expect(
|
await expect(
|
||||||
finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture)
|
finder.findPyPyVersion(
|
||||||
|
'pypy-3.6-v7.3.x',
|
||||||
|
architecture,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
)
|
||||||
).resolves.toEqual({
|
).resolves.toEqual({
|
||||||
resolvedPythonVersion: '3.6.12',
|
resolvedPythonVersion: '3.6.12',
|
||||||
resolvedPyPyVersion: '7.3.3'
|
resolvedPyPyVersion: '7.3.3'
|
||||||
});
|
});
|
||||||
|
expect(spyCoreAddPath).toHaveBeenCalled();
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'pythonLocation',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'PKG_CONFIG_PATH',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw on invalid input format', async () => {
|
it('throw on invalid input format', async () => {
|
||||||
await expect(
|
await expect(
|
||||||
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture)
|
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false)
|
||||||
).rejects.toThrow();
|
).rejects.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw on invalid input format pypy3.7-7.3.x', async () => {
|
it('throw on invalid input format pypy3.7-7.3.x', async () => {
|
||||||
await expect(
|
await expect(
|
||||||
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture)
|
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false)
|
||||||
).rejects.toThrow();
|
).rejects.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -220,18 +315,150 @@ describe('findPyPyVersion', () => {
|
|||||||
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||||
spyChmodSync.mockImplementation(() => undefined);
|
spyChmodSync.mockImplementation(() => undefined);
|
||||||
await expect(
|
await expect(
|
||||||
finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture)
|
finder.findPyPyVersion(
|
||||||
|
'pypy-3.7-v7.3.x',
|
||||||
|
architecture,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
)
|
||||||
).resolves.toEqual({
|
).resolves.toEqual({
|
||||||
resolvedPythonVersion: '3.7.9',
|
resolvedPythonVersion: '3.7.9',
|
||||||
resolvedPyPyVersion: '7.3.3'
|
resolvedPyPyVersion: '7.3.3'
|
||||||
});
|
});
|
||||||
|
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, 'PyPy', '3.7.7', architecture)
|
||||||
|
);
|
||||||
|
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||||
|
spyChmodSync.mockImplementation(() => undefined);
|
||||||
|
await expect(
|
||||||
|
finder.findPyPyVersion(
|
||||||
|
'pypy-3.7-v7.3.x',
|
||||||
|
architecture,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
).resolves.toEqual({
|
||||||
|
resolvedPythonVersion: '3.7.9',
|
||||||
|
resolvedPyPyVersion: '7.3.3'
|
||||||
|
});
|
||||||
|
expect(spyCoreAddPath).not.toHaveBeenCalled();
|
||||||
|
expect(spyCoreExportVariable).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw if release is not found', async () => {
|
it('throw if release is not found', async () => {
|
||||||
await expect(
|
await expect(
|
||||||
finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture)
|
finder.findPyPyVersion(
|
||||||
).rejects.toThrowError(
|
'pypy-3.7-v7.5.x',
|
||||||
|
architecture,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
).rejects.toThrow(
|
||||||
`PyPy version 3.7 (v7.5.x) with arch ${architecture} not found`
|
`PyPy version 3.7 (v7.5.x) with arch ${architecture} not found`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('check-latest enabled version found and used from toolcache', async () => {
|
||||||
|
await expect(
|
||||||
|
finder.findPyPyVersion(
|
||||||
|
'pypy-3.6-v7.3.x',
|
||||||
|
architecture,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
).resolves.toEqual({
|
||||||
|
resolvedPythonVersion: '3.6.12',
|
||||||
|
resolvedPyPyVersion: '7.3.3'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(
|
||||||
|
'Resolved as PyPy 7.3.3 with Python (3.6.12)'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('check-latest enabled version found and install successfully', async () => {
|
||||||
|
spyCacheDir = jest.spyOn(tc, 'cacheDir');
|
||||||
|
spyCacheDir.mockImplementation(() =>
|
||||||
|
path.join(toolDir, 'PyPy', '3.7.7', architecture)
|
||||||
|
);
|
||||||
|
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||||
|
spyChmodSync.mockImplementation(() => undefined);
|
||||||
|
await expect(
|
||||||
|
finder.findPyPyVersion(
|
||||||
|
'pypy-3.7-v7.3.x',
|
||||||
|
architecture,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
).resolves.toEqual({
|
||||||
|
resolvedPythonVersion: '3.7.9',
|
||||||
|
resolvedPyPyVersion: '7.3.3'
|
||||||
|
});
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(
|
||||||
|
'Resolved as PyPy 7.3.3 with Python (3.7.9)'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 pypyPath = '';
|
||||||
|
if (semver.satisfies('3.8.8', semverRange)) {
|
||||||
|
pypyPath = path.join(toolDir, 'PyPy', '3.8.8', architecture);
|
||||||
|
}
|
||||||
|
return pypyPath;
|
||||||
|
});
|
||||||
|
await expect(
|
||||||
|
finder.findPyPyVersion(
|
||||||
|
'pypy-3.8-v7.3.x',
|
||||||
|
architecture,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
).resolves.toEqual({
|
||||||
|
resolvedPythonVersion: '3.8.8',
|
||||||
|
resolvedPyPyVersion: '7.3.3'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(
|
||||||
|
'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'
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+201
-19
@@ -1,6 +1,7 @@
|
|||||||
import io = require('@actions/io');
|
import * as io from '@actions/io';
|
||||||
import fs = require('fs');
|
import os from 'os';
|
||||||
import path = require('path');
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
const toolDir = path.join(
|
const toolDir = path.join(
|
||||||
__dirname,
|
__dirname,
|
||||||
@@ -19,29 +20,199 @@ process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
|||||||
process.env['RUNNER_TEMP'] = tempDir;
|
process.env['RUNNER_TEMP'] = tempDir;
|
||||||
|
|
||||||
import * as tc from '@actions/tool-cache';
|
import * as tc from '@actions/tool-cache';
|
||||||
|
import * as core from '@actions/core';
|
||||||
import * as finder from '../src/find-python';
|
import * as finder from '../src/find-python';
|
||||||
import * as installer from '../src/install-python';
|
import * as installer from '../src/install-python';
|
||||||
|
|
||||||
const manifestData = require('./data/versions-manifest.json');
|
import manifestData from './data/versions-manifest.json';
|
||||||
|
|
||||||
describe('Finder tests', () => {
|
describe('Finder tests', () => {
|
||||||
|
let writeSpy: jest.SpyInstance;
|
||||||
|
let spyCoreAddPath: jest.SpyInstance;
|
||||||
|
let spyCoreExportVariable: jest.SpyInstance;
|
||||||
|
const env = process.env;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
writeSpy = jest.spyOn(process.stdout, 'write');
|
||||||
|
writeSpy.mockImplementation(() => {});
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {...env};
|
||||||
|
spyCoreAddPath = jest.spyOn(core, 'addPath');
|
||||||
|
spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
jest.restoreAllMocks();
|
||||||
|
process.env = env;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Finds Python if it is installed', async () => {
|
it('Finds Python if it is installed', async () => {
|
||||||
|
const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
||||||
|
getBooleanInputSpy.mockImplementation(input => false);
|
||||||
|
|
||||||
const pythonDir: string = path.join(toolDir, 'Python', '3.0.0', 'x64');
|
const pythonDir: string = path.join(toolDir, 'Python', '3.0.0', 'x64');
|
||||||
await io.mkdirP(pythonDir);
|
await io.mkdirP(pythonDir);
|
||||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||||
await finder.findPythonVersion('3.x', 'x64');
|
await finder.useCpythonVersion('3.x', 'x64', true, false, false);
|
||||||
|
expect(spyCoreAddPath).toHaveBeenCalled();
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'pythonLocation',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'PKG_CONFIG_PATH',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Finds Python if it is installed without environment update', async () => {
|
||||||
|
const pythonDir: string = path.join(toolDir, 'Python', '3.0.0', '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 finder.useCpythonVersion('3.x', 'x64', false, false, false);
|
||||||
|
expect(spyCoreAddPath).not.toHaveBeenCalled();
|
||||||
|
expect(spyCoreExportVariable).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Finds stable Python version if it is not installed, but exists in the manifest', async () => {
|
it('Finds stable Python version if it is not installed, but exists in the manifest', async () => {
|
||||||
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
|
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
|
||||||
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
||||||
|
|
||||||
|
const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
||||||
|
getBooleanInputSpy.mockImplementation(input => false);
|
||||||
|
|
||||||
|
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.3', 'x64', true, false, false)
|
||||||
|
).resolves.toEqual({
|
||||||
|
impl: 'CPython',
|
||||||
|
version: '1.2.3'
|
||||||
|
});
|
||||||
|
expect(spyCoreAddPath).toHaveBeenCalled();
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'pythonLocation',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'PKG_CONFIG_PATH',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Finds pre-release Python version in the manifest', async () => {
|
||||||
|
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
|
||||||
|
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
||||||
|
|
||||||
|
const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
||||||
|
getBooleanInputSpy.mockImplementation(input => false);
|
||||||
|
|
||||||
|
const installSpy: jest.SpyInstance = jest.spyOn(
|
||||||
|
installer,
|
||||||
|
'installCpythonFromRelease'
|
||||||
|
);
|
||||||
|
installSpy.mockImplementation(async () => {
|
||||||
|
const pythonDir: string = path.join(
|
||||||
|
toolDir,
|
||||||
|
'Python',
|
||||||
|
'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 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 () => {
|
||||||
|
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
|
||||||
|
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
||||||
|
|
||||||
|
const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
||||||
|
getBooleanInputSpy.mockImplementation(input => true);
|
||||||
|
|
||||||
|
const cnSpy: jest.SpyInstance = jest.spyOn(process.stdout, 'write');
|
||||||
|
cnSpy.mockImplementation(line => {
|
||||||
|
// uncomment to debug
|
||||||
|
// process.stderr.write('write:' + line + '\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
const addPathSpy: jest.SpyInstance = jest.spyOn(core, 'addPath');
|
||||||
|
addPathSpy.mockImplementation(() => null);
|
||||||
|
|
||||||
|
const infoSpy: jest.SpyInstance = jest.spyOn(core, 'info');
|
||||||
|
infoSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
const debugSpy: jest.SpyInstance = jest.spyOn(core, 'debug');
|
||||||
|
debugSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
const pythonDir: string = path.join(toolDir, 'Python', '1.2.2', 'x64');
|
||||||
|
const expPath: string = path.join(toolDir, 'Python', '1.2.3', 'x64');
|
||||||
|
|
||||||
|
const installSpy: jest.SpyInstance = jest.spyOn(
|
||||||
|
installer,
|
||||||
|
'installCpythonFromRelease'
|
||||||
|
);
|
||||||
|
installSpy.mockImplementation(async () => {
|
||||||
|
await io.mkdirP(expPath);
|
||||||
|
fs.writeFileSync(`${expPath}.complete`, 'hello');
|
||||||
|
});
|
||||||
|
|
||||||
|
const tcFindSpy: jest.SpyInstance = jest.spyOn(tc, 'find');
|
||||||
|
tcFindSpy
|
||||||
|
.mockImplementationOnce(() => '')
|
||||||
|
.mockImplementationOnce(() => expPath);
|
||||||
|
|
||||||
|
await io.mkdirP(pythonDir);
|
||||||
|
await io.rmRF(path.join(toolDir, 'Python', '1.2.3'));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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(
|
||||||
|
'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);
|
||||||
|
expect(spyCoreAddPath).toHaveBeenCalled();
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'pythonLocation',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||||
|
'PKG_CONFIG_PATH',
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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(
|
const installSpy: jest.SpyInstance = jest.spyOn(
|
||||||
installer,
|
installer,
|
||||||
'installCpythonFromRelease'
|
'installCpythonFromRelease'
|
||||||
@@ -52,10 +223,15 @@ describe('Finder tests', () => {
|
|||||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||||
});
|
});
|
||||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||||
await finder.findPythonVersion('1.2.3', 'x64');
|
await expect(
|
||||||
|
finder.useCpythonVersion('1.2', 'x64', false, false, false)
|
||||||
|
).resolves.toEqual({
|
||||||
|
impl: 'CPython',
|
||||||
|
version: '1.2.3'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Finds pre-release Python version in the manifest', async () => {
|
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');
|
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
|
||||||
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
||||||
|
|
||||||
@@ -67,32 +243,38 @@ describe('Finder tests', () => {
|
|||||||
const pythonDir: string = path.join(
|
const pythonDir: string = path.join(
|
||||||
toolDir,
|
toolDir,
|
||||||
'Python',
|
'Python',
|
||||||
'1.2.3-beta.2',
|
'1.1.0-beta.2',
|
||||||
'x64'
|
'x64'
|
||||||
);
|
);
|
||||||
await io.mkdirP(pythonDir);
|
await io.mkdirP(pythonDir);
|
||||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||||
});
|
});
|
||||||
// This will throw if it doesn't find it in the manifest (because no such version exists)
|
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||||
await finder.findPythonVersion('1.2.3-beta.2', 'x64');
|
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 () => {
|
it('Errors if Python is not installed', async () => {
|
||||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||||
let thrown = false;
|
let thrown = false;
|
||||||
try {
|
try {
|
||||||
await finder.findPythonVersion('3.300000', 'x64');
|
await finder.useCpythonVersion('3.300000', 'x64', true, false, false);
|
||||||
} catch {
|
} catch {
|
||||||
thrown = true;
|
thrown = true;
|
||||||
}
|
}
|
||||||
expect(thrown).toBeTruthy();
|
expect(thrown).toBeTruthy();
|
||||||
});
|
expect(spyCoreAddPath).not.toHaveBeenCalled();
|
||||||
|
expect(spyCoreExportVariable).not.toHaveBeenCalled();
|
||||||
it('Finds PyPy if it is installed', async () => {
|
|
||||||
const pythonDir: string = path.join(toolDir, 'PyPy', '2.0.0', 'x64');
|
|
||||||
await io.mkdirP(pythonDir);
|
|
||||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
|
||||||
// This will throw if it doesn't find it in the cache (because no such version exists)
|
|
||||||
await finder.findPythonVersion('pypy2', 'x64');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user