Compare commits

..
9 Commits
Author SHA1 Message Date
Dmitry Shibanov 0f07f7f756 update actions/core (#625) 2023-03-27 13:07:33 +02:00
Nikita BykovandNikita Bykov 9f3aa2c73d Add test.yml to releases/v1 branch (#176)
* added test.yml

* replaced ubuntu-16.04 with ubuntu-20.04

Co-authored-by: Nikita Bykov <v-nibyko@microsoft.com>
2021-01-04 11:16:26 +01:00
Nikita BykovandNikita Bykov 152ba7c4dd added Scripts to PATH on Windows (#173)
Co-authored-by: Nikita Bykov <v-nibyko@microsoft.com>
2020-12-18 15:32:23 +01:00
Maxim Lobanov da8703fb23 update dist file (#166) 2020-12-08 11:00:17 -05:00
Konrad Pabjan accf675719 Update @actions/core (#142) 2020-09-30 21:55:38 +02:00
Konrad Pabjan 614aa4aa1e Merge pull request #76 from actions/master
Update releases branch with latest changes
2020-03-26 16:49:22 +01:00
Konrad Pabjan 53d19faf05 Merge pull request #69 from actions/master
Update releases/v1 with changes from master
2020-03-09 10:55:07 +01:00
Konrad Pabjan 948e5343c7 Revert "Update releases/v1 with changes from master (#67)" (#68)
This reverts commit bdd6409dc1.
2020-03-09 10:51:55 +01:00
bdd6409dc1 Update releases/v1 with changes from master (#67)
* Use ncc instead of saving node_modules

* Add branding and correctly point to main file

* Cleanup

* Update release script

* PR Feedback

* Update README.md

* Update README.md

* Update contributors.md

* Update description

* use node-version instead of version (deprecated)

* Update contributors.md

* Update README.md

* Update README.md

* Create yaml-lint-config.yml

* Create lint-yaml.yml

* Update README.md

* Update README.md

* Update contributors.md

* Update README.md

* Update terminology in comments

* Spelling & grammar

* Consistent file name references

* ncc build

* Address YAML linting errors

* Fix quotes

* Bump handlebars from 4.1.2 to 4.5.3

Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.5.3.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.5.3)

Signed-off-by: dependabot[bot] <support@github.com>

* Run main workflow on PRs

* Match README to action.yml

* Update dist/index.js

* Update checkout action to v2

* Fix cross-platform build matrix example

* output installed version number after setup (#51)

* output installed version number after setup

* set output for the installed version

* Setup python + self hosted runners documentation

* Updates to npm packages (#66)

* npm package updates

* Updates to ncc build

* Update action.yml

* Update action.yml

Co-authored-by: Konrad Pabjan <Konrad.Pabjan@microsoft.com>
Co-authored-by: Edward Thomson <ethomson@edwardthomson.com>
Co-authored-by: conao3 <conao3@gmail.com>
Co-authored-by: Brian Cristante <brcrista@microsoft.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rui Chen <chenrui333@gmail.com>
Co-authored-by: Madhuri Gummalla <madhurig@github.com>
Co-authored-by: Ye-hyoung Kang <keepyourhonor@gmail.com>
Co-authored-by: Robin Daumann <26201853+robindaumann@users.noreply.github.com>
2020-03-09 10:38:24 +01:00
115 changed files with 12224 additions and 148038 deletions
+1 -2
View File
@@ -1,2 +1 @@
* text=auto eol=lf * text=auto eol=lf
.licenses/** -diff linguist-generated=true
-1
View File
@@ -1 +0,0 @@
* @actions/actions-service
-38
View File
@@ -1,38 +0,0 @@
---
name: Bug report
about: Create a bug report
title: ''
labels: bug, 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 bug report, please make sure to check for similar existing issues -->
**Description:**
A clear and concise description of what the bug is.
**Action version:**
Specify the action version
**Platform:**
- [ ] Ubuntu
- [ ] macOS
- [ ] Windows
**Runner type:**
- [ ] Hosted
- [ ] Self-hosted
**Tools version:**
<!--- Please list all of the affected Python versions (`3.8.2`, etc.)-->
**Repro steps:**
A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link.
**Expected behavior:**
A description of what you expected to happen.
**Actual behavior:**
A description of what is actually happening.
-1
View File
@@ -1 +0,0 @@
blank_issues_enabled: false
-18
View File
@@ -1,18 +0,0 @@
---
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! -->
-9
View File
@@ -1,9 +0,0 @@
**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.
-52
View File
@@ -1,52 +0,0 @@
# `dist/index.js` is a special file in Actions.
# When you reference an action with `uses:` in a workflow,
# `index.js` is the code that will run.
# For our project, we generate this file through a build process from other source files.
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
name: Check dist/
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
jobs:
check-dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Rebuild the dist/ directory
run: npm run build
- name: Compare the expected and actual dist/ directories
run: |
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
git diff
exit 1
fi
id: diff
# If index.js was different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@v2
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:
name: dist
path: dist/
-47
View File
@@ -1,47 +0,0 @@
name: "Code scanning - action"
on:
push:
branches: [ 'main' ]
pull_request:
schedule:
- cron: '25 3 * * 5'
jobs:
CodeQL-Build:
strategy:
fail-fast: false
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@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
-131
View File
@@ -1,131 +0,0 @@
name: e2e-cache
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- main
- releases/*
paths-ignore:
- '**.md'
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.7-v7.x']
steps:
- uses: actions/checkout@v3
- 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@v3
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pipenv'
- name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies
shell: pwsh
run: |
mv ./__tests__/data/Pipfile.lock .
mv ./__tests__/data/Pipfile .
if ("${{ matrix.python-version }}" -Match "pypy") {
pipenv install --keep-outdated --python pypy
} else {
pipenv install --keep-outdated --python ${{ matrix.python-version }}
}
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.8']
steps:
- uses: actions/checkout@v3
- name: Install poetry
run: pipx install poetry
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Init pyproject.toml
run: poetry init -n
- name: Install dependencies
run: poetry add flake8
python-pip-dependencies-caching-path:
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.7-v7.x']
steps:
- uses: actions/checkout@v3
- 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 }})
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@v3
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pipenv'
cache-dependency-path: '**/pipenv-requirements.txt'
- name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies
shell: pwsh
run: |
mv ./__tests__/data/Pipfile.lock .
mv ./__tests__/data/Pipfile .
if ("${{ matrix.python-version }}" -Match "pypy") {
pipenv install --keep-outdated --python pypy
} else {
pipenv install --keep-outdated --python ${{ matrix.python-version }}
}
-29
View File
@@ -1,29 +0,0 @@
name: Licensed
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
name: Check licenses
steps:
- uses: actions/checkout@v2
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm
- run: npm ci
- name: Install licensed
run: |
cd $RUNNER_TEMP
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.4.4/licensed-3.4.4-linux-x64.tar.gz
sudo tar -xzf licensed.tar.gz
sudo mv licensed /usr/local/bin/licensed
- run: licensed status
+12
View File
@@ -0,0 +1,12 @@
name: Lint YAML
on: [pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Lint action.yml
uses: ibiqlik/action-yamllint@master
with:
file_or_dir: action.yml
config_file: yaml-lint-config.yml
@@ -1,27 +0,0 @@
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.1.0
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
-93
View File
@@ -1,93 +0,0 @@
name: Validate PyPy e2e
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
schedule:
- cron: 30 3 * * *
jobs:
setup-pypy:
name: Setup PyPy ${{ matrix.pypy }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
pypy:
- 'pypy-2.7'
- 'pypy-3.7'
- 'pypy3.9'
- 'pypy-2.7-v7.3.4'
- 'pypy-3.7-v7.3.5'
- 'pypy-3.7-v7.3.4'
- 'pypy-3.7-v7.3.x'
- 'pypy-3.7-v7.x'
- 'pypy-2.7-v7.3.4rc1'
- 'pypy-3.7-nightly'
- 'pypy3.8-v7.3.7'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-python ${{ matrix.pypy }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.pypy }}
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: PyPy and Python version
run: python --version
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
- name: Assert PyPy is running
run: |
import platform
assert platform.python_implementation().lower() == "pypy"
shell: python
- name: Assert expected binaries (or symlinks) are present
run: |
EXECUTABLE=${{ matrix.pypy }}
EXECUTABLE=${EXECUTABLE/pypy-/pypy} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
${EXECUTABLE} --version
shell: bash
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-18.04, ubuntu-latest]
pypy: ['pypy2.7', 'pypy3.7', 'pypy3.8', 'pypy3.9-nightly']
steps:
- name: Checkout
uses: actions/checkout@v3
- 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))'
-174
View File
@@ -1,174 +0,0 @@
name: Validate Python e2e
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
schedule:
- cron: 30 3 * * *
workflow_dispatch:
jobs:
setup-versions-from-manifest:
name: Setup ${{ matrix.python }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version: ${{ matrix.python }}
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: 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-18.04, ubuntu-20.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
steps:
- name: Checkout
uses: actions/checkout@v3
- 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-pre-release-version-from-manifest:
name: Setup 3.9.0-beta.4 ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: setup-python 3.9.0-beta.4
id: setup-python
uses: ./
with:
python-version: '3.9.0-beta.4'
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("Python 3.9.0b4" -ne "$pythonVersion"){
Write-Host "The current version is $pythonVersion; expected version is 3.9.0b4"
exit 1
}
$pythonVersion
shell: pwsh
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-dev-version:
name: Setup 3.9-dev ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: setup-python 3.9-dev
id: setup-python
uses: ./
with:
python-version: '3.9-dev'
- name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
shell: bash
- name: Validate version
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.9.') }}
shell: bash
- name: Run simple code
run: python -c 'import math; print(math.factorial(5))'
setup-versions-noenv:
name: Setup ${{ matrix.python }} ${{ matrix.os }} (noenv)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: ["3.7", "3.8", "3.9", "3.10"]
steps:
- name: Checkout
uses: actions/checkout@v3
- 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))'
+77
View File
@@ -0,0 +1,77 @@
name: Validate 'setup-python'
on:
pull_request:
paths-ignore:
- '**.md'
jobs:
default-version:
name: Setup default version
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, 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-python:
name: Setup ${{ matrix.python }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
python: [3.5, 3.6, 3.7, 3.8, 3.9]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-python ${{ matrix.python }}
uses: ./
with:
python-version: ${{ matrix.python }}
- name: Validate version
run: |
$pythonVersion = (python --version)
if ("$pythonVersion" -notlike "Python ${{ matrix.python }}.*"){
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-pypy:
name: Setup PyPy ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-python pypy3
uses: ./
with:
python-version: 'pypy3'
- name: setup-python pypy2
uses: ./
with:
python-version: 'pypy2'
+6 -81
View File
@@ -1,13 +1,5 @@
name: Main workflow name: Main workflow
on: on: [push, pull_request]
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs: jobs:
run: run:
name: Run name: Run
@@ -19,83 +11,16 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Set Node.js 16.x - name: Set Node.js 12.x
uses: actions/setup-node@v3 uses: actions/setup-node@v1
with: with:
node-version: 16.x node-version: 12.x
cache: npm
- name: npm ci - name: npm install
run: npm ci run: npm install
- name: Lint - name: Lint
run: npm run format-check run: npm run format-check
- name: npm test - name: npm test
run: npm test run: npm test
- name: Run with setup-python 2.7
uses: ./
with:
python-version: 2.7
- name: Verify 2.7
run: python __tests__/verify-python.py 2.7
- name: Run with setup-python 3.5
uses: ./
with:
python-version: 3.5
- name: Verify 3.5
run: python __tests__/verify-python.py 3.5
- name: Run with setup-python 3.6
uses: ./
with:
python-version: 3.6
- name: Verify 3.6
run: python __tests__/verify-python.py 3.6
- name: Run with setup-python 3.7
uses: ./
with:
python-version: 3.7
- name: Verify 3.7
run: python __tests__/verify-python.py 3.7
- name: Run with setup-python 3.8
uses: ./
with:
python-version: 3.8
- name: Verify 3.8
run: python __tests__/verify-python.py 3.8
- name: Run with setup-python 3.7.5
uses: ./
with:
python-version: 3.7.5
- name: Verify 3.7.5
run: python __tests__/verify-python.py 3.7.5
- name: Run with setup-python 3.6.7
uses: ./
with:
python-version: 3.6.7
- name: Verify 3.6.7
run: python __tests__/verify-python.py 3.6.7
- name: Run with setup-python 3.8.1
uses: ./
with:
python-version: 3.8.1
- name: Verify 3.8.1
run: python __tests__/verify-python.py 3.8.1
- name: Run with setup-python 3.10
id: cp310
uses: ./
with:
python-version: "3.10"
- name: Verify 3.10
run: python __tests__/verify-python.py 3.10
- name: Run python-path sample 3.10
run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version
-15
View File
@@ -1,15 +0,0 @@
sources:
npm: true
allowed:
- apache-2.0
- bsd-2-clause
- bsd-3-clause
- isc
- mit
- cc0-1.0
- unlicense
- 0bsd
reviewed:
npm:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-76
View File
@@ -1,76 +0,0 @@
# 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
+35 -348
View File
@@ -1,4 +1,4 @@
# setup-python V4 # setup-python
<p align="left"> <p align="left">
<a href="https://github.com/actions/setup-python"><img alt="GitHub Actions status" src="https://github.com/actions/setup-python/workflows/Main%20workflow/badge.svg"></a> <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>
@@ -6,21 +6,8 @@
This action sets up a Python environment for use in actions by: This action sets up a Python environment for use in actions by:
- optionally installing and adding to PATH a version of Python that is already installed in the tools cache. - optionally installing a version of Python and adding to PATH. Note that this action only uses versions of Python already installed in the cache. The action will fail if no matching versions are found.
- 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. - registering problem matchers for error output
- failing if a specific version of Python is not preinstalled or available for download.
- optionally caching dependencies for pip, pipenv and poetry.
- registering problem matchers for error output.
# What's new
- 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
- Support for built-in caching of pip, pipenv and poetry dependencies
- Support for `.python-version` file
# Usage # Usage
@@ -29,24 +16,14 @@ See [action.yml](action.yml)
Basic: Basic:
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-python@v4 - uses: actions/setup-python@v1
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.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
- run: python my_script.py - run: python my_script.py
``` ```
Read Python version from file:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version-file: '.python-version' # Read python version from a file
- run: python my_script.py
```
Matrix Testing: Matrix Testing:
```yaml ```yaml
jobs: jobs:
@@ -54,12 +31,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
python-version: [ '2.x', '3.x', 'pypy2.7', 'pypy3.7', 'pypy3.8' ] python-version: [ '2.x', '3.x', 'pypy2', 'pypy3' ]
name: Python ${{ matrix.python-version }} sample name: Python ${{ matrix.python-version }} sample
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up Python - name: Setup python
uses: actions/setup-python@v4 uses: actions/setup-python@v1
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
architecture: x64 architecture: x64
@@ -74,153 +51,29 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['2.7', '3.7', '3.8', '3.9', '3.10', 'pypy2.7', 'pypy3.8'] python-version: [2.7, 3.6, 3.7, 3.8, pypy2, pypy3]
exclude: exclude:
- os: macos-latest - os: macos-latest
python-version: '3.8' python-version: 3.8
- os: windows-latest - os: windows-latest
python-version: '3.6' python-version: 3.6
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v1
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Display Python version - name: Display Python version
run: 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.7.4', '3.8', '3.9', '3.10']
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- run: python my_script.py
```
Download and set up an accurate pre-release version of Python:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11.0-alpha.1'
- run: python my_script.py
```
Download and set up the latest available version of Python (includes both pre-release and stable versions):
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11.0-alpha - 3.11.0' # SemVer's version range syntax
- run: python my_script.py
```
Download and set up the latest patch version of Python (for specified major & minor versions):
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11-dev'
- run: python my_script.py
```
Download and set up the latest stable version of Python (for specified major version):
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- run: python my_script.py
```
Download and set up PyPy:
```yaml
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- 'pypy3.7' # the latest available version of PyPy that supports Python 3.7
- 'pypy3.7-v7.3.3' # Python 3.7 and PyPy 7.3.3
- 'pypy3.8' # the latest available version of PyPy that supports Python 3.8
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- run: python my_script.py
```
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.
An output is available with the absolute path of the python interpreter executable if you need it:
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
id: cp310
with:
python-version: "3.10"
- run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version
```
>The environment variable `pythonLocation` also becomes available after Python or PyPy installation. It contains the absolute path to the folder where the desired version of Python or PyPy is installed.
# Getting started with Python + Actions # Getting started with Python + Actions
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). 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).
# Available versions of Python
`setup-python` is able to configure Python from two sources:
- Preinstalled versions of Python in the tools cache on GitHub-hosted runners.
- For detailed information regarding the available versions of Python that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
- For 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.
- Use `-dev` instead of a patch number (e.g., `3.11-dev`) to install the latest patch version release for a given minor version, *alpha and beta releases included*.
- Downloadable Python versions from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)).
- 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
**Note:** Python versions used in this action are generated in the [python-versions](https://github.com/actions/python-versions) repository. For macOS and Ubuntu images python versions are built from the source code. For Windows the python-versions repository uses installation executable. For more information please refer to the [python-versions](https://github.com/actions/python-versions) repository.
# 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 `pypy3.7` or `pypy-3.7`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy3.7-v7.3.3` or `pypy-3.7-v7.3.3`.
- Downloadable PyPy versions from the [official PyPy site](https://downloads.python.org/pypy/).
- 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 # 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. GitHub hosted runners have a tools cache that comes with 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 | || Location |
|------|-------| |------|-------|
@@ -229,204 +82,38 @@ GitHub hosted runners have a tools cache that comes with a few versions of Pytho
|**PyPy Tool Cache**|`RUNNER_TOOL_CACHE/PyPy/*`| |**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. 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: [Install-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/linux/scripts/installers/Install-Toolset.ps1) [Configure-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/linux/scripts/installers/Configure-Toolset.ps1) - [Tools cache setup for Ubuntu](https://github.com/actions/virtual-environments/blob/master/images/linux/scripts/installers/hosted-tool-cache.sh)
- Tools cache setup for Windows: [Install-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/win/scripts/Installers/Install-Toolset.ps1) [Configure-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/win/scripts/Installers/Configure-Toolset.ps1) - [Tools cache setup for Windows](https://github.com/actions/virtual-environments/blob/master/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>]` or `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.
```
pypy3.7 or pypy-3.7 # the latest available version of PyPy that supports Python 3.7
pypy3.8 or pypy-3.8 # the latest available version of PyPy that supports Python 3.8
pypy2.7 or pypy-2.7 # the latest available version of PyPy that supports Python 2.7
pypy3.7-v7.3.3 or pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3
pypy3.7-v7.x or pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x
pypy3.7-v7.3.3rc1 or pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy
pypy3.7-nightly or pypy-3.7-nightly # Python 3.7 and nightly PyPy
```
Note: `pypy2` and `pypy3` have been removed in v3. Use the format above instead.
# Caching packages dependencies
The action has built-in functionality for caching and restoring dependencies. It uses [actions/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default.
The action defaults to searching for a dependency file (`requirements.txt` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Use `cache-dependency-path` for cases where multiple dependency files are used, they are located in different subdirectories or different files for the hash want to be used.
- For pip, the action will cache global cache directory
- For pipenv, the action will cache virtualenv directory
- For poetry, the action will cache virtualenv directory
**Please 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 that can lead to an increase in total build time.
The requirements file format allows to specify dependency versions using logical operators (for example chardet>=3.0.4) or specify 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.
**Caching pip dependencies:**
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.9'
cache: 'pip'
- run: pip install -r requirements.txt
```
**Caching pipenv dependencies:**
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.9'
cache: 'pipenv'
- name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- run: pipenv install
```
**Caching poetry dependencies:**
```yaml
steps:
- uses: actions/checkout@v3
- name: Install poetry
run: pipx install poetry
- uses: actions/setup-python@v4
with:
python-version: '3.9'
cache: 'poetry'
- run: poetry install
- run: poetry run pytest
```
**Using wildcard patterns to cache dependencies**
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.9'
cache: 'pip'
cache-dependency-path: '**/requirements-dev.txt'
- run: pip install -r subdirectory/requirements-dev.txt
```
**Using a list of file paths to cache dependencies**
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.9'
cache: 'pipenv'
cache-dependency-path: |
server/app/Pipfile.lock
__test__/app/Pipfile.lock
- name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- run: pipenv install
```
**Using a list of wildcard patterns to cache dependencies**
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
cache: 'pip'
cache-dependency-path: |
**/setup.cfg
**/requirements*.txt
- run: pip install -e . -r subdirectory/requirements-dev.txt
```
# Environment variables
The `update-environment` flag defaults to `true`.
With this setting, the action will add/update environment variables (e.g. `PATH`, `PKG_CONFIG_PATH`, `pythonLocation`) for `python` to just work out of the box.
If `update-environment` is set to `false`, the action will not add/update environment variables.
This can prove useful if you want the only side-effect to be to ensure python is installed and rely on the `python-path` output to run python.
Such a requirement on side-effect could be because you don't want your composite action messing with your user's workflows.
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
id: cp310
with:
python-version: '3.10'
update-environment: false
- run: ${{ steps.cp310.outputs.python-path }} my_script.py
```
# Using `setup-python` with a self hosted runner # 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 would like to use `setup-python` on a self-hosted runner, you will need to download all versions of Python & PyPy that you would like and setup a similar tools cache locally for 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.
- By default runner downloads and install the tools to `/opt/hostedtoolcache`. The environment variable called `AGENT_TOOLSDIRECTORY` can be set to change this location.
- 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.
- Create an global environment variable called `AGENT_TOOLSDIRECTORY` that will point to the root directory of where you want the tools installed. The env variable is preferrably global as it must be set in the shell that will install the tools cache, along with the shell that the runner will be using.
- This env variable is used internally by the runner to set the `RUNNER_TOOL_CACHE` env variable
- Example for Administrator Powershell: `[System.Environment]::SetEnvironmentVariable("AGENT_TOOLSDIRECTORY", "C:\hostedtoolcache\windows", [System.EnvironmentVariableTarget]::Machine)` (restart the shell afterwards)
- Download the appropriate NPM packages from the [GitHub Actions NPM registry](https://github.com/orgs/actions/packages)
- Make sure to have `npm` installed, and then [configure npm for use with GitHub packages](https://help.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-npm-for-use-with-github-packages#authenticating-to-github-package-registry)
- Create an empty npm project for easier installation (`npm init`) in the tools cache directory. You can delete `package.json`, `package.lock.json` and `node_modules` after all tools get installed
- Before downloading a specific package, create an empty folder for the version of Python/PyPY that is being installed. If downloading Python 3.6.8 for example, create `C:\hostedtoolcache\windows\Python\3.6.8`
- Once configured, download a specific package by calling `npm install`. Note (if downloading a PyPy package on Windows, you will need 7zip installed along with `7z.exe` added to your PATH)
- Each NPM package has multiple versions that determine the version of Python or PyPy that should be installed.
- `npm install @actions/toolcache-python-windows-x64@3.7.61579791175` for example installs Python 3.7.6 while `npm install @actions/toolcache-python-windows-x64@3.6.81579791177` installs Python 3.6.8
- You can browse and find all available versions of a package by searching the GitHub Actions NPM registry
![image](https://user-images.githubusercontent.com/16109154/76194005-87aeb400-61e5-11ea-9b21-ef9111247f84.png)
# Using Python without `setup-python` # 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`. `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`.
# Using `setup-python` on GHES # Available versions of Python
`setup-python` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Python distributions, `setup-python` downloads distributions from [`actions/python-versions`](https://github.com/actions/python-versions) on github.com (outside of the appliance). These calls to `actions/python-versions` are made via unauthenticated requests, which are limited to [60 requests per hour per IP](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting). If more requests are made within the time frame, then you will start to see rate-limit errors during download that read `##[error]API rate limit exceeded for...`. For detailed information regarding the available versions of Python that are installed see [Software installed on GitHub-hosted runners](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners)
To avoid hitting rate-limit problems, we recommend [setting up your own runner tool cache](https://docs.github.com/en/enterprise-server@2.22/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access#about-the-included-setup-actions-and-the-runner-tool-cache).
# License # 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 [Contributor's Guide](docs/contributors.md)
-230
View File
@@ -1,230 +0,0 @@
import * as core from '@actions/core';
import * as cache from '@actions/cache';
import * as exec from '@actions/exec';
import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
describe('restore-cache', () => {
const pipFileLockHash =
'a3bdcc71289e4979ca9e051810d81999cc99823109faf6912e17ff14c8e621a6';
const requirementsHash =
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
const requirementsLinuxHash =
'2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c';
const poetryLockHash =
'571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836';
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 saveSatetSpy: jest.SpyInstance;
let getStateSpy: jest.SpyInstance;
let setOutputSpy: jest.SpyInstance;
// cache spy
let restoreCacheSpy: jest.SpyInstance;
// exec spy
let getExecOutputSpy: 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);
saveSatetSpy = jest.spyOn(core, 'saveState');
saveSatetSpy.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};
}
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;
}
);
});
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)
).toThrowError(`Caching for '${packageManager}' is not supported`);
}
);
});
describe('Restore dependencies', () => {
it.each([
['pip', '3.8.12', undefined, requirementsHash],
['pip', '3.8.12', '**/requirements-linux.txt', requirementsLinuxHash],
[
'pip',
'3.8.12',
'__tests__/data/requirements-linux.txt',
requirementsLinuxHash
],
['pip', '3.8.12', '__tests__/data/requirements.txt', requirementsHash],
['pipenv', '3.9.1', undefined, pipFileLockHash],
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
['poetry', '3.9.1', undefined, poetryLockHash]
])(
'restored dependencies for %s by primaryKey',
async (packageManager, pythonVersion, dependencyFile, fileHash) => {
const cacheDistributor = getCacheDistributor(
packageManager,
pythonVersion,
dependencyFile
);
await cacheDistributor.restoreCache();
expect(infoSpy).toHaveBeenCalledWith(
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-${fileHash}`
);
},
30000
);
it.each([
['pip', '3.8.12', 'requirements-linux.txt', 'requirements-linux.txt'],
['pip', '3.8.12', 'requirements.txt', 'requirements.txt'],
['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']
])(
'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.toThrowError(
`No file in ${process.cwd()} matched to [${cacheDependencyPath
.split('\n')
.join(',')}], make sure you have checked out the target repository`
);
}
);
});
describe('Dependencies changed', () => {
it.each([
['pip', '3.8.12', undefined, pipFileLockHash],
['pip', '3.8.12', '**/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', undefined, requirementsHash],
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
['poetry', '3.9.1', undefined, 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();
});
});
-275
View File
@@ -1,275 +0,0 @@
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 saveSatetSpy: 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);
saveSatetSpy = jest.spyOn(core, 'saveState');
saveSatetSpy.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';
await run();
expect(getInputSpy).toHaveBeenCalled();
expect(debugSpy).toHaveBeenCalledWith(
`paths for caching are ${__dirname}`
);
expect(getStateSpy).toHaveBeenCalledTimes(3);
expect(infoSpy).toHaveBeenCalledWith(
`Cache hit occurred on the primary key ${requirementsHash}, not saving cache.`
);
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('should not save cache for pipenv', async () => {
inputs['cache'] = 'pipenv';
await run();
expect(getInputSpy).toHaveBeenCalled();
expect(debugSpy).toHaveBeenCalledWith(
`paths for caching are ${__dirname}`
);
expect(getStateSpy).toHaveBeenCalledTimes(3);
expect(infoSpy).toHaveBeenCalledWith(
`Cache hit occurred on the primary key ${requirementsHash}, not saving cache.`
);
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('should not save cache for pipenv', async () => {
inputs['cache'] = 'pipenv';
await run();
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';
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';
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';
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';
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 fail workflow', async () => {
inputs['cache'] = 'npm';
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).toHaveBeenCalled();
});
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
inputs = {};
});
});
-14
View File
@@ -1,14 +0,0 @@
#!/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}"
-13
View File
@@ -1,13 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flake8 = "==4.0.1"
numpy = "==1.23.0"
[dev-packages]
[requires]
python_version = "*"
-80
View File
@@ -1,80 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "e9c37110984955621040e2dc8548c026eb8466c23db1b8e69430289b10be8938"
},
"pipfile-spec": 6,
"requires": {
"python_version": "*"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"flake8": {
"hashes": [
"sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d",
"sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"
],
"index": "pypi",
"version": "==4.0.1"
},
"mccabe": {
"hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
],
"version": "==0.6.1"
},
"numpy": {
"hashes": [
"sha256:092f5e6025813e64ad6d1b52b519165d08c730d099c114a9247c9bb635a2a450",
"sha256:196cd074c3f97c4121601790955f915187736f9cf458d3ee1f1b46aff2b1ade0",
"sha256:1c29b44905af288b3919803aceb6ec7fec77406d8b08aaa2e8b9e63d0fe2f160",
"sha256:2b2da66582f3a69c8ce25ed7921dcd8010d05e59ac8d89d126a299be60421171",
"sha256:5043bcd71fcc458dfb8a0fc5509bbc979da0131b9d08e3d5f50fb0bbb36f169a",
"sha256:58bfd40eb478f54ff7a5710dd61c8097e169bc36cc68333d00a9bcd8def53b38",
"sha256:79a506cacf2be3a74ead5467aee97b81fca00c9c4c8b3ba16dbab488cd99ba10",
"sha256:94b170b4fa0168cd6be4becf37cb5b127bd12a795123984385b8cd4aca9857e5",
"sha256:97a76604d9b0e79f59baeca16593c711fddb44936e40310f78bfef79ee9a835f",
"sha256:98e8e0d8d69ff4d3fa63e6c61e8cfe2d03c29b16b58dbef1f9baa175bbed7860",
"sha256:ac86f407873b952679f5f9e6c0612687e51547af0e14ddea1eedfcb22466babd",
"sha256:ae8adff4172692ce56233db04b7ce5792186f179c415c37d539c25de7298d25d",
"sha256:bd3fa4fe2e38533d5336e1272fc4e765cabbbde144309ccee8675509d5cd7b05",
"sha256:d0d2094e8f4d760500394d77b383a1b06d3663e8892cdf5df3c592f55f3bff66",
"sha256:d54b3b828d618a19779a84c3ad952e96e2c2311b16384e973e671aa5be1f6187",
"sha256:d6ca8dabe696c2785d0c8c9b0d8a9b6e5fdbe4f922bde70d57fa1a2848134f95",
"sha256:d8cc87bed09de55477dba9da370c1679bd534df9baa171dd01accbb09687dac3",
"sha256:f0f18804df7370571fb65db9b98bf1378172bd4e962482b857e612d1fec0f53e",
"sha256:f1d88ef79e0a7fa631bb2c3dda1ea46b32b1fe614e10fedd611d3d5398447f2f",
"sha256:f9c3fc2adf67762c9fe1849c859942d23f8d3e0bee7b5ed3d4a9c3eeb50a2f07",
"sha256:fc431493df245f3c627c0c05c2bd134535e7929dbe2e602b80e42bf52ff760bc",
"sha256:fe8b9683eb26d2c4d5db32cd29b38fdcf8381324ab48313b5b69088e0e355379"
],
"index": "pypi",
"version": "==1.23.0"
},
"pycodestyle": {
"hashes": [
"sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20",
"sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.8.0"
},
"pyflakes": {
"hashes": [
"sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c",
"sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.4.0"
}
},
"develop": {}
}
-2
View File
@@ -1,2 +0,0 @@
numpy==1.22.3
pandas==1.4.2
-413
View File
@@ -1,413 +0,0 @@
[[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"},
]
-533
View File
@@ -1,533 +0,0 @@
[
{
"pypy_version": "7.3.3",
"python_version": "3.6.12",
"stable": true,
"latest_pypy": true,
"date": "2020-11-21",
"files": [
{
"filename": "pypy3.6-v7.3.3-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3-aarch64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3-linux32.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3-linux64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3-darwin64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3-darwin64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3-win32.zip"
},
{
"filename": "pypy3.6-v7.3.3-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3-s390x.tar.bz2"
}
]
},
{
"pypy_version": "7.3.3rc1",
"python_version": "3.6.12",
"stable": false,
"latest_pypy": false,
"date": "2020-11-11",
"files": [
{
"filename": "pypy3.6-v7.3.3rc1-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3rc1-aarch64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3-linux32rc1.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3rc1-linux32.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3rc1-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3rc1-linux64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3rc1-osx64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3rc1-osx64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.3-win32rc1.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3rc1-win32.zip"
},
{
"filename": "pypy3.6-v7.3.3rc1-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.3rc1-s390x.tar.bz2"
}
]
},
{
"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",
"python_version": "3.7.7",
"stable": false,
"latest_pypy": false,
"date": "2020-11-11",
"files": [
{
"filename": "test.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "test.tar.bz2"
},
{
"filename": "test.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "test.tar.bz2"
},
{
"filename": "test.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "test.tar.bz2"
},
{
"filename": "test.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "test.tar.bz2"
},
{
"filename": "test.zip",
"arch": "x86",
"platform": "win32",
"download_url": "test.zip"
},
{
"filename": "test.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "test.tar.bz2"
}
]
},
{
"pypy_version": "7.3.3",
"python_version": "3.7.9",
"stable": true,
"latest_pypy": true,
"date": "2020-11-21",
"files": [
{
"filename": "pypy3.7-v7.3.3-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.3-aarch64.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.3-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.3-linux32.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.3-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.3-linux64.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.3-osx64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.3-osx64.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.3-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.3-win32.zip"
},
{
"filename": "pypy3.7-v7.3.3-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.3-s390x.tar.bz2"
}
]
},
{
"pypy_version": "7.3.3",
"python_version": "2.7.18",
"stable": true,
"latest_pypy": true,
"date": "2020-11-21",
"files": [
{
"filename": "pypy2.7-v7.3.3-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.3-aarch64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.3-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.3-linux32.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.3-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.3-linux64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.3-osx64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.3-osx64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.3-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.3-win32.zip"
},
{
"filename": "pypy2.7-v7.3.3-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.3-s390x.tar.bz2"
}
]
},
{
"pypy_version": "7.3.2",
"python_version": "3.6.9",
"stable": true,
"latest_pypy": true,
"date": "2020-09-25",
"files": [
{
"filename": "pypy3.6-v7.3.2-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.2-aarch64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.2-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.2-linux32.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.2-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.2-linux64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.2-osx64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.2-osx64.tar.bz2"
},
{
"filename": "pypy3.6-v7.3.2-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.2-win32.zip"
},
{
"filename": "pypy3.6-v7.3.2-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.3.2-s390x.tar.bz2"
}
]
},
{
"pypy_version": "7.3.2",
"python_version": "3.7.9",
"stable": true,
"latest_pypy": false,
"date": "2020-09-25",
"files": [
{
"filename": "pypy3.7-v7.3.2-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.2-aarch64.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.2-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.2-linux32.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.2-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.2-linux64.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.2-osx64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.2-osx64.tar.bz2"
},
{
"filename": "pypy3.7-v7.3.2-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.2-win32.zip"
},
{
"filename": "pypy3.7-v7.3.2-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy3.7-v7.3.2-s390x.tar.bz2"
}
]
},
{
"pypy_version": "7.3.2",
"python_version": "2.7.13",
"stable": true,
"latest_pypy": true,
"date": "2020-09-25",
"files": [
{
"filename": "pypy2.7-v7.3.2-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.2-aarch64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.2-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.2-linux32.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.2-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.2-linux64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.2-osx64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.2-osx64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.2-win32.zip",
"arch": "x86",
"platform": "win32",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.2-win32.zip"
},
{
"filename": "pypy2.7-v7.3.2-s390x.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "https://test.download.python.org/pypy/pypy2.7-v7.3.2-s390x.tar.bz2"
}
]
},
{
"pypy_version": "nightly",
"python_version": "2.7",
"stable": false,
"latest_pypy": false,
"files": [
{
"filename": "filename.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.zip",
"arch": "x86",
"platform": "win32",
"download_url": "http://nightlyBuilds.org/filename.zip"
},
{
"filename": "filename.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
}
]
},
{
"pypy_version": "nightly",
"python_version": "3.7",
"stable": false,
"latest_pypy": false,
"files": [
{
"filename": "filename.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.zip",
"arch": "x86",
"platform": "win32",
"download_url": "http://nightlyBuilds.org/filename.zip"
},
{
"filename": "filename.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
}
]
},
{
"pypy_version": "nightly",
"python_version": "3.6",
"stable": false,
"latest_pypy": false,
"files": [
{
"filename": "filename.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
},
{
"filename": "filename.zip",
"arch": "x86",
"platform": "win32",
"download_url": "http://nightlyBuilds.org/filename.zip"
},
{
"filename": "filename.tar.bz2",
"arch": "s390x",
"platform": "linux",
"download_url": "http://nightlyBuilds.org/filename.tar.bz2"
}
]
}
]
-12
View File
@@ -1,12 +0,0 @@
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
-47
View File
@@ -1,47 +0,0 @@
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
-52
View File
@@ -1,52 +0,0 @@
[
{
"version": "1.2.3",
"stable": true,
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6",
"files": [
{
"filename": "sometool-1.2.3-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-linux-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-darwin-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-win32-x64.tar.gz",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-win32-x64.tar.gz"
}
]
},
{
"version": "1.2.3-beta.2",
"stable": false,
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5",
"files": [
{
"filename": "sometool-1.2.3-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5/sometool-1.2.3-linux-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-darwin-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-win32-x64.tar.gz",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-win32-x64.tar.gz"
}
]
}
]
-301
View File
@@ -1,301 +0,0 @@
import fs from 'fs';
import * as utils from '../src/utils';
import {HttpClient} from '@actions/http-client';
import * as ifm from '@actions/http-client/interfaces';
import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec';
import * as core from '@actions/core';
import * as path from 'path';
import * as semver from 'semver';
import * as finder from '../src/find-pypy';
import {
IPyPyManifestRelease,
IS_WINDOWS,
validateVersion,
getPyPyVersionFromPath
} from '../src/utils';
const manifestData = require('./data/pypy.json');
let architecture: string;
if (IS_WINDOWS) {
architecture = 'x86';
} else {
architecture = 'x64';
}
const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp');
describe('parsePyPyVersion', () => {
it.each([
['pypy-3.6-v7.3.3', {pythonVersion: '3.6', pypyVersion: 'v7.3.3'}],
['pypy-3.6-v7.3.x', {pythonVersion: '3.6', pypyVersion: 'v7.3.x'}],
['pypy-3.6-v7.x', {pythonVersion: '3.6', pypyVersion: 'v7.x'}],
['pypy-3.6', {pythonVersion: '3.6', pypyVersion: 'x'}],
['pypy-3.6-nightly', {pythonVersion: '3.6', pypyVersion: 'nightly'}],
['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) => {
expect(finder.parsePyPyVersion(input)).toEqual(expected);
});
it.each(['', 'pypy-', 'pypy', 'p', 'notpypy-'])(
'throw on invalid input "%s"',
input => {
expect(() => finder.parsePyPyVersion(input)).toThrowError(
"Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy<python-version>' or 'pypy-<python-version>'. See README for examples and documentation."
);
}
);
it.each(['pypy-2', 'pypy-3', 'pypy2', 'pypy3', 'pypy3.x', 'pypy3.8.10'])(
'throw on invalid input "%s"',
input => {
expect(() => finder.parsePyPyVersion(input)).toThrowError(
"Invalid format of Python version for PyPy. Python version should be specified in format 'x.y'. See README for examples and documentation."
);
}
);
});
describe('getPyPyVersionFromPath', () => {
it('/fake/toolcache/PyPy/3.6.5/x64 -> 3.6.5', () => {
expect(getPyPyVersionFromPath('/fake/toolcache/PyPy/3.6.5/x64')).toEqual(
'3.6.5'
);
});
});
describe('findPyPyToolCache', () => {
const actualPythonVersion = '3.6.17';
const actualPyPyVersion = '7.5.4';
const pypyPath = path.join('PyPy', actualPythonVersion, architecture);
let tcFind: jest.SpyInstance;
let spyReadExactPyPyVersion: jest.SpyInstance;
beforeEach(() => {
tcFind = jest.spyOn(tc, 'find');
tcFind.mockImplementation((toolname: string, pythonVersion: string) => {
const semverVersion = new semver.Range(pythonVersion);
return semver.satisfies(actualPythonVersion, semverVersion)
? pypyPath
: '';
});
spyReadExactPyPyVersion = jest.spyOn(utils, 'readExactPyPyVersionFile');
spyReadExactPyPyVersion.mockImplementation(() => actualPyPyVersion);
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it('PyPy exists on the path and versions are satisfied', () => {
expect(finder.findPyPyToolCache('3.6.17', 'v7.5.4', architecture)).toEqual({
installDir: pypyPath,
resolvedPythonVersion: actualPythonVersion,
resolvedPyPyVersion: actualPyPyVersion
});
});
it('PyPy exists on the path and versions are satisfied with semver', () => {
expect(finder.findPyPyToolCache('3.6', 'v7.5.x', architecture)).toEqual({
installDir: pypyPath,
resolvedPythonVersion: actualPythonVersion,
resolvedPyPyVersion: actualPyPyVersion
});
});
it("PyPy exists on the path, but Python version doesn't match", () => {
expect(finder.findPyPyToolCache('3.7', 'v7.5.4', architecture)).toEqual({
installDir: '',
resolvedPythonVersion: '',
resolvedPyPyVersion: ''
});
});
it("PyPy exists on the path, but PyPy version doesn't match", () => {
expect(finder.findPyPyToolCache('3.6', 'v7.5.1', architecture)).toEqual({
installDir: null,
resolvedPythonVersion: '',
resolvedPyPyVersion: ''
});
});
});
describe('findPyPyVersion', () => {
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 spyReadExactPyPyVersion: jest.SpyInstance;
let spyFsReadDir: jest.SpyInstance;
let spyWriteExactPyPyVersionFile: jest.SpyInstance;
let spyCacheDir: jest.SpyInstance;
let spyChmodSync: jest.SpyInstance;
let spyCoreAddPath: jest.SpyInstance;
let spyCoreExportVariable: jest.SpyInstance;
const env = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {...env};
tcFind = jest.spyOn(tc, 'find');
tcFind.mockImplementation((tool: string, version: string) => {
const semverRange = new semver.Range(version);
let pypyPath = '';
if (semver.satisfies('3.6.12', semverRange)) {
pypyPath = path.join(toolDir, 'PyPy', '3.6.12', architecture);
}
return pypyPath;
});
spyWriteExactPyPyVersionFile = jest.spyOn(
utils,
'writeExactPyPyVersionFile'
);
spyWriteExactPyPyVersionFile.mockImplementation(() => null);
spyReadExactPyPyVersion = jest.spyOn(utils, 'readExactPyPyVersionFile');
spyReadExactPyPyVersion.mockImplementation(() => '7.3.3');
spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'PyPy'));
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) => ['PyPyTest']);
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation(
async (): Promise<ifm.ITypedResponse<IPyPyManifestRelease[]>> => {
const result = JSON.stringify(manifestData);
return {
statusCode: 200,
headers: {},
result: JSON.parse(result) as IPyPyManifestRelease[]
};
}
);
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 PyPy in toolcache', async () => {
await expect(
finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true)
).resolves.toEqual({
resolvedPythonVersion: '3.6.12',
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 () => {
await expect(
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true)
).rejects.toThrow();
});
it('throw on invalid input format pypy3.7-7.3.x', async () => {
await expect(
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true)
).rejects.toThrow();
});
it('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, true)
).resolves.toEqual({
resolvedPythonVersion: '3.7.9',
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)
).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 () => {
await expect(
finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true)
).rejects.toThrowError(
`PyPy version 3.7 (v7.5.x) with arch ${architecture} not found`
);
});
});
+12 -105
View File
@@ -18,126 +18,33 @@ const tempDir = path.join(
process.env['RUNNER_TOOL_CACHE'] = toolDir; process.env['RUNNER_TOOL_CACHE'] = toolDir;
process.env['RUNNER_TEMP'] = tempDir; process.env['RUNNER_TEMP'] = tempDir;
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';
const manifestData = require('./data/versions-manifest.json');
describe('Finder tests', () => { describe('Finder tests', () => {
let spyCoreAddPath: jest.SpyInstance;
let spyCoreExportVariable: jest.SpyInstance;
const env = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {...env};
spyCoreAddPath = jest.spyOn(core, 'addPath');
spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
process.env = env;
});
it('Finds Python if it is installed', async () => { it('Finds Python if it is installed', async () => {
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 (because no such version exists)
await finder.useCpythonVersion('3.x', 'x64', true); await finder.findPythonVersion('3.x', 'x64');
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);
expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled();
});
it('Finds stable Python version if it is not installed, but exists in the manifest', async () => {
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => {
const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', 'x64');
await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
});
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await finder.useCpythonVersion('1.2.3', 'x64', true);
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 installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => {
const pythonDir: string = path.join(
toolDir,
'Python',
'1.2.3-beta.2',
'x64'
);
await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
});
// This will throw if it doesn't find it in the manifest (because no such version exists)
await finder.useCpythonVersion('1.2.3-beta.2', 'x64', true);
expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'pythonLocation',
expect.anything()
);
expect(spyCoreExportVariable).toHaveBeenCalledWith(
'PKG_CONFIG_PATH',
expect.anything()
);
}); });
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 (because no such version exists)
let thrown = false; let thrown = false;
try { try {
await finder.useCpythonVersion('3.300000', 'x64', true); await finder.findPythonVersion('3.300000', 'x64');
} 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');
}); });
}); });
-230
View File
@@ -1,230 +0,0 @@
import fs from 'fs';
import {HttpClient} from '@actions/http-client';
import * as ifm from '@actions/http-client/interfaces';
import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec';
import * as path from 'path';
import * as installer from '../src/install-pypy';
import {
IPyPyManifestRelease,
IPyPyManifestAsset,
IS_WINDOWS
} from '../src/utils';
const manifestData = require('./data/pypy.json');
let architecture: string;
if (IS_WINDOWS) {
architecture = 'x86';
} else {
architecture = 'x64';
}
const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp');
describe('pypyVersionToSemantic', () => {
it.each([
['7.3.3rc1', '7.3.3-rc.1'],
['7.3.3', '7.3.3'],
['7.3.x', '7.3.x'],
['7.x', '7.x'],
['nightly', 'nightly']
])('%s -> %s', (input, expected) => {
expect(installer.pypyVersionToSemantic(input)).toEqual(expected);
});
});
describe('findRelease', () => {
const result = JSON.stringify(manifestData);
const releases = JSON.parse(result) as IPyPyManifestRelease[];
const extension = IS_WINDOWS ? '.zip' : '.tar.bz2';
const extensionName = IS_WINDOWS
? `${process.platform}${extension}`
: `${process.platform}64${extension}`;
const files: IPyPyManifestAsset = {
filename: `pypy3.6-v7.3.3-${extensionName}`,
arch: architecture,
platform: process.platform,
download_url: `https://test.download.python.org/pypy/pypy3.6-v7.3.3-${extensionName}`
};
it("Python version is found, but PyPy version doesn't match", () => {
const pythonVersion = '3.6';
const pypyVersion = '7.3.7';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
).toEqual(null);
});
it('Python version is found and PyPy version matches', () => {
const pythonVersion = '3.6';
const pypyVersion = '7.3.3';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
).toEqual({
foundAsset: files,
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: pypyVersion
});
});
it('Python version is found in toolcache and PyPy version matches semver', () => {
const pythonVersion = '3.6';
const pypyVersion = '7.x';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
).toEqual({
foundAsset: files,
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.3.3'
});
});
it('Python and preview version of PyPy are found', () => {
const pythonVersion = '3.7';
const pypyVersion = installer.pypyVersionToSemantic('7.3.3rc2');
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
).toEqual({
foundAsset: {
filename: `test${extension}`,
arch: architecture,
platform: process.platform,
download_url: `test${extension}`
},
resolvedPythonVersion: '3.7.7',
resolvedPyPyVersion: '7.3.3rc2'
});
});
it('Python version with latest PyPy is found', () => {
const pythonVersion = '3.6';
const pypyVersion = 'x';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
).toEqual({
foundAsset: files,
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.3.3'
});
});
it('Nightly release is found', () => {
const pythonVersion = '3.6';
const pypyVersion = 'nightly';
const filename = IS_WINDOWS ? 'filename.zip' : 'filename.tar.bz2';
expect(
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
).toEqual({
foundAsset: {
filename: filename,
arch: architecture,
platform: process.platform,
download_url: `http://nightlyBuilds.org/${filename}`
},
resolvedPythonVersion: '3.6',
resolvedPyPyVersion: pypyVersion
});
});
});
describe('installPyPy', () => {
let tcFind: 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('PyPy', '3.6.12', architecture));
spyDownloadTool = jest.spyOn(tc, 'downloadTool');
spyDownloadTool.mockImplementation(() => path.join(tempDir, 'PyPy'));
spyExtractZip = jest.spyOn(tc, 'extractZip');
spyExtractZip.mockImplementation(() => tempDir);
spyExtractTar = jest.spyOn(tc, 'extractTar');
spyExtractTar.mockImplementation(() => tempDir);
spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation(() => ['PyPyTest']);
spyFsWriteFile = jest.spyOn(fs, 'writeFileSync');
spyFsWriteFile.mockImplementation(() => undefined);
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockImplementation(
async (): Promise<ifm.ITypedResponse<IPyPyManifestRelease[]>> => {
const result = JSON.stringify(manifestData);
return {
statusCode: 200,
headers: {},
result: JSON.parse(result) as IPyPyManifestRelease[]
};
}
);
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.installPyPy('7.3.3', '3.6.17', architecture)
).rejects.toThrowError(
`PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found`
);
expect(spyHttpClient).toHaveBeenCalled();
expect(spyDownloadTool).not.toHaveBeenCalled();
expect(spyExec).not.toHaveBeenCalled();
});
it('found and install PyPy', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'PyPy', '3.6.12', architecture)
);
spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined);
await expect(
installer.installPyPy('7.3.x', '3.6.12', architecture)
).resolves.toEqual({
installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture),
resolvedPythonVersion: '3.6.12',
resolvedPyPyVersion: '7.3.3'
});
expect(spyHttpClient).toHaveBeenCalled();
expect(spyDownloadTool).toHaveBeenCalled();
expect(spyExistsSync).toHaveBeenCalled();
expect(spyCacheDir).toHaveBeenCalled();
expect(spyExec).toHaveBeenCalled();
});
});
-76
View File
@@ -1,76 +0,0 @@
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import {
validateVersion,
validatePythonVersionFormatForPyPy,
isCacheFeatureAvailable
} from '../src/utils';
jest.mock('@actions/cache');
jest.mock('@actions/core');
describe('validatePythonVersionFormatForPyPy', () => {
it.each([
['3.6', true],
['3.7', true],
['3.6.x', false],
['3.7.x', false],
['3.x', false],
['3', false]
])('%s -> %s', (input, expected) => {
expect(validatePythonVersionFormatForPyPy(input)).toEqual(expected);
});
});
describe('validateVersion', () => {
it.each([
['v7.3.3', true],
['v7.3.x', true],
['v7.x', true],
['x', true],
['v7.3.3-rc.1', true],
['nightly', true],
['v7.3.b', false],
['3.6', true],
['3.b', false],
['3', true]
])('%s -> %s', (input, expected) => {
expect(validateVersion(input)).toEqual(expected);
});
});
describe('isCacheFeatureAvailable', () => {
it('isCacheFeatureAvailable disabled on GHES', () => {
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => false);
try {
process.env['GITHUB_SERVER_URL'] = 'http://example.com';
isCacheFeatureAvailable();
} catch (error) {
expect(error).toHaveProperty(
'message',
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.'
);
} finally {
delete process.env['GITHUB_SERVER_URL'];
}
});
it('isCacheFeatureAvailable disabled on dotcom', () => {
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => false);
const infoMock = jest.spyOn(core, 'warning');
const message =
'The runner was not able to contact the cache service. Caching will be skipped';
try {
process.env['GITHUB_SERVER_URL'] = 'http://github.com';
expect(isCacheFeatureAvailable()).toBe(false);
expect(infoMock).toHaveBeenCalledWith(message);
} finally {
delete process.env['GITHUB_SERVER_URL'];
}
});
it('isCacheFeatureAvailable is enabled', () => {
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => true);
expect(isCacheFeatureAvailable()).toBe(true);
});
});
-22
View File
@@ -1,22 +0,0 @@
import sys
argCount = len(sys.argv) - 1
if argCount == 1:
expectedVersion = sys.argv[1]
versions = len(expectedVersion.split("."))
majorMinor = str(sys.version_info[0]) + '.' + str(sys.version_info[1])
if versions == 2:
# Test only major and minor version
if expectedVersion != majorMinor:
raise Exception("Incorrect major + minor version detected\nExpected: " + expectedVersion + "\nActual: " + majorMinor)
elif versions == 3:
# Test major, minor and micro version
majorMinorMicro = majorMinor + '.' + str(sys.version_info[2])
if expectedVersion != majorMinorMicro:
raise Exception("Incorrect major + minor + micro version detected\nExpected: " + expectedVersion + "\nActual: " + majorMinorMicro)
else:
raise Exception("Incorrect number of arguments supplied")
print("Correct version of Python " + expectedVersion + " detected")
else:
raise Exception("Incorrect number of arguments supplied")
+5 -22
View File
@@ -4,34 +4,17 @@ description: 'Set up a specific version of Python and add the command-line tools
author: 'GitHub' author: 'GitHub'
inputs: inputs:
python-version: python-version:
description: "Version range or exact version of Python to use, using SemVer's version range syntax. Reads from .python-version if unset." description: "Version range or exact version of a Python version to use, using SemVer's version range syntax."
python-version-file: default: '3.x'
description: "File containing the Python version to use. Example: .python-version"
cache:
description: 'Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv, poetry.'
required: false
architecture: architecture:
description: 'The target architecture (x86, x64) of the Python interpreter.' description: 'The target architecture (x86, x64) of the Python interpreter.'
token: default: 'x64'
description: Used to pull python distributions from actions/python-versions. Since there's a default, this is typically not supplied by the user.
default: ${{ github.token }}
cache-dependency-path:
description: 'Used to specify the path to dependency files. Supports wildcards or a list of file names for caching multiple dependencies.'
update-environment:
description: 'Set this option if you want the action to update environment variables.'
default: true
outputs: outputs:
python-version: python-version:
description: "The installed python version. Useful when given a version range as input." description: "The installed python version. Useful when given a version range as input."
cache-hit:
description: 'A boolean value to indicate a cache entry was found'
python-path:
description: "The absolute path to the Python executable."
runs: runs:
using: 'node16' using: 'node12'
main: 'dist/setup/index.js' main: 'dist/index.js'
post: 'dist/cache-save/index.js'
post-if: success()
branding: branding:
icon: 'code' icon: 'code'
color: 'yellow' color: 'yellow'
-59168
View File
File diff suppressed because one or more lines are too long
+8970
View File
File diff suppressed because it is too large Load Diff
-65684
View File
File diff suppressed because one or more lines are too long
-93
View File
@@ -1,93 +0,0 @@
## 0. Caching dependencies
Date: 2021-10-01
Status: Accepted
## Context
`actions/setup-python` is one the most popular python's action in GitHub Actions. A lot of customers use it in conjunction with `actions/cache` to speed up dependencies installation.
See more examples on proper usage in [actions/cache documentation](https://github.com/actions/cache/blob/main/examples.md#python---pip).
## Goals & Anti-Goals
Integration of caching functionality into `actions/setup-python` action will bring the following benefits for action users:
- Decrease the entry threshold for using the cache for Python dependencies and simplify initial configuration
- Simplify YAML pipelines by reducing the need for additional steps to enable caching
- More users will use caching for Python so users will have faster builds!
We will add support for Pip and Pipenv dependency caching.
We won't pursue the goal to provide wide customization of caching in the scope of `actions/setup-python` action. The purpose of this integration is to cover ~90% of basic use-cases. If users need flexible customization, we will advise them to use `actions/cache` directly.
## Decision
- Add a `cache` input parameter to `actions/setup-python`. For now the input will accept the following values:
- pip - enable caching for pip dependencies
- pipenv - enable caching for pipenv dependencies
- '' - disable caching (default value)
- Cache feature will be disabled by default to make sure that we don't break existing customers.
- Action will try to search dependencies files (requirements.txt for pip and Pipfile.lock for pipenv) in the repository root (or relative to the repository root, if patterns are used) and throw error if no one is found.
- The hash of found file will be used as part of cache key (the same approach like actions/cache recommends)
- The following cache key will be used for pip: `setup-python-${{ runner.os }}-pip-${{ hashFiles('<package-file-path>') }}`
- The following cache key will be used for pipenv: `setup-python-${{ runner.os }}-python-${{ python-version }}-pipenv-${{ hashFiles('<package-file-path>') }}`. We add the python version to the cache key because the created virtualenv folder with the project name contains a copy of the python binary as a symlink to paths like `/opt/hostedtoolcache/Python/3.7.11`, so the cache can be fetched with a wrong python version. See details in the related [pull request](https://github.com/actions/cache/pull/607) in the actions/cache.
- Action will save the packages global cache:
- Pip (retrieved via pip cache dir). The command is available With pip 20.1 or later. We always update pip during installation, that is why this command should be available.
- Pipenv (default cache paths):
- ~/.local/share/virtualenvs (macOS)
- ~/.virtualenvs (Windows)
- ~/.local/share/virtualenvs (Ubuntu)
- Add a `cache-dependency-path` input parameter to `actions/setup-python`. The new input will accept an array or regex of dependency files. The field will accept a path (relative to the repository root) to dependency files. If the provided path contains wildcards, the action will search all matching files and calculate a common hash like the `${{ hashFiles('**/requirements-dev.txt') }}` YAML construction does
## Example of real use-cases
- Pip package manager
```
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
cache: pip
```
- Pipenv package manager
```
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
cache: pipenv
```
- With `cache-dependency-path`
```
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
cache: pip
cache-dependency-path: |
**/requirements-dev.txt
**/requirements-test.txt
**/requirements.txt
```
```
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
cache: pip
cache-dependency-path: **/requirements-dev.txt
```
## Release process
As soon as the functionality is implemented, we will release a minor update of the action. No need to bump the major version since there are no breaking changes for existing users. After that, we will update [starter-workflows](https://github.com/actions/starter-workflows/blob/main/ci/python-app.yml) and [GitHub Action documentation](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#caching-dependencies).

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