mirror of
https://github.com/actions/setup-python.git
synced 2025-04-20 03:53:30 +00:00
resolved comments, update readme, add e2e tests.
This commit is contained in:
parent
739154f76b
commit
3d613a97df
47
.github/workflows/test-pypy.yml
vendored
Normal file
47
.github/workflows/test-pypy.yml
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
name: Validate PyPy e2e
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
schedule:
|
||||||
|
- cron: 0 0 * * *
|
||||||
|
|
||||||
|
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-20.04]
|
||||||
|
pypy:
|
||||||
|
- 'pypy-2.7'
|
||||||
|
- 'pypy-3.6'
|
||||||
|
- 'pypy-3.7'
|
||||||
|
- 'pypy-2.7-v7.3.2'
|
||||||
|
- 'pypy-3.6-v7.3.2'
|
||||||
|
- 'pypy-3.7-v7.3.2'
|
||||||
|
- 'pypy-3.6-v7.3.x'
|
||||||
|
- 'pypy-3.7-v7.x'
|
||||||
|
- 'pypy-3.6-v7.3.3rc1'
|
||||||
|
- 'pypy-3.7-nightly'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: setup-python ${{ matrix.pypy }}
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.pypy }}
|
||||||
|
|
||||||
|
- name: PyPy and Python version
|
||||||
|
run: python --version
|
||||||
|
|
||||||
|
- name: Run simple code
|
||||||
|
run: python -c 'import math; print(math.factorial(5))'
|
@ -1,4 +1,4 @@
|
|||||||
name: Validate 'setup-python'
|
name: Validate Python e2e
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@ -18,7 +18,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04]
|
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -38,7 +38,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04]
|
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
||||||
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
|
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -68,7 +68,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04]
|
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -91,13 +91,13 @@ jobs:
|
|||||||
- name: Run simple code
|
- name: Run simple code
|
||||||
run: python -c 'import math; print(math.factorial(5))'
|
run: python -c 'import math; print(math.factorial(5))'
|
||||||
|
|
||||||
setup-pypy:
|
setup-pypy-legacy-way:
|
||||||
name: Setup PyPy ${{ matrix.os }}
|
name: Setup PyPy ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04]
|
os: [macos-latest, windows-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
57
README.md
57
README.md
@ -17,6 +17,7 @@ This action sets up a Python environment for use in actions by:
|
|||||||
- Allows for pinning to a specific patch version of Python without the worry of it ever being removed or changed.
|
- 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.
|
- Automatic setup and download of Python packages if using a self-hosted runner.
|
||||||
- Support for pre-release versions of Python.
|
- Support for pre-release versions of Python.
|
||||||
|
- Support for installation any version of PyPy on-flight
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [ '2.x', '3.x', 'pypy2', 'pypy3' ]
|
python-version: [ '2.x', '3.x', 'pypy-2.7', 'pypy-3.6', 'pypy-3.7' ]
|
||||||
name: Python ${{ matrix.python-version }} sample
|
name: Python ${{ matrix.python-version }} sample
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@ -60,7 +61,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
python-version: [2.7, 3.6, 3.7, 3.8, pypy2, pypy3]
|
python-version: [2.7, 3.6, 3.7, 3.8, pypy-2.7, pypy-3.6]
|
||||||
exclude:
|
exclude:
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
@ -91,7 +92,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- run: python my_script.py
|
- run: python my_script.py
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Download and set up an accurate pre-release version of Python:
|
Download and set up an accurate pre-release version of Python:
|
||||||
@ -114,6 +114,27 @@ steps:
|
|||||||
- run: python my_script.py
|
- run: python my_script.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Download and set up PyPy:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
python-version:
|
||||||
|
- pypy-3.6 # the latest available version of PyPy
|
||||||
|
- pypy-3.7 # the latest available version of PyPy
|
||||||
|
- pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
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 [Available versions of PyPy](#available-versions-of-pypy) section.
|
||||||
|
|
||||||
# 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).
|
||||||
@ -129,7 +150,21 @@ Check out our detailed guide on using [Python with GitHub Actions](https://help.
|
|||||||
- 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.
|
- If the exact patch version doesn't matter to you, specifying just the major and minor version will get you the latest preinstalled patch version. In the previous example, the version spec `3.8` will use the `3.8.2` Python version found in the cache.
|
||||||
- Downloadable Python versions from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)).
|
- 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.
|
- 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.
|
- If there is a specific version of Python that is not available, you can open an issue here
|
||||||
|
|
||||||
|
# Available versions of PyPy
|
||||||
|
|
||||||
|
`setup-python` is able to configure PyPy from two sources:
|
||||||
|
|
||||||
|
- Preinstalled versions of PyPy in the tools cache on GitHub-hosted runners
|
||||||
|
- For detailed information regarding the available versions of PyPy that are installed see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
|
||||||
|
- For the latest PyPy release, all version of Python are cached.
|
||||||
|
- Cache is updated with 1-2 weeks delay. if you specify PyPy as `pypy-3.6`, the version from cache will be used although a new version is available. If you need to start using the recently released version right after release, you should specify exact PyPy version `pypy-3.6-v7.3.3`.
|
||||||
|
|
||||||
|
- Downloadable PyPy versions from [official PyPy site](https://downloads.python.org/pypy/).
|
||||||
|
- All available versions are listed in the [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
|
||||||
|
|
||||||
@ -155,6 +190,20 @@ You should specify only a major and minor version if you are okay with the most
|
|||||||
- There will be a single patch version already installed on each runner for every minor version of Python that is supported.
|
- 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.
|
- 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.
|
- 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>]`.
|
||||||
|
Parameter `<pypy_version>` is optional and can be skipped. The latest version will be used in this case.
|
||||||
|
|
||||||
|
```
|
||||||
|
pypy-3.6 # the latest available version of PyPy
|
||||||
|
pypy-3.7 # the latest available version of PyPy
|
||||||
|
pypy-2.7 # the latest available version of PyPy
|
||||||
|
pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3
|
||||||
|
pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x
|
||||||
|
pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy
|
||||||
|
pypy-3.7-nightly # Python 3.7 and nightly PyPy
|
||||||
|
```
|
||||||
|
|
||||||
# Using `setup-python` with a self hosted runner
|
# Using `setup-python` with a self hosted runner
|
||||||
|
|
||||||
|
42
dist/index.js
vendored
42
dist/index.js
vendored
@ -1154,7 +1154,8 @@ function findPyPyToolCache(pythonVersion, pypyVersion, architecture) {
|
|||||||
function parsePyPyVersion(versionSpec) {
|
function parsePyPyVersion(versionSpec) {
|
||||||
const versions = versionSpec.split('-').filter(item => !!item);
|
const versions = versionSpec.split('-').filter(item => !!item);
|
||||||
if (versions.length < 2) {
|
if (versions.length < 2) {
|
||||||
throw new Error("Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-<python-version>'. See readme for more examples.");
|
core.setFailed("Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-<python-version>'. See README for examples and documentation.");
|
||||||
|
process.exit();
|
||||||
}
|
}
|
||||||
const pythonVersion = versions[1];
|
const pythonVersion = versions[1];
|
||||||
let pypyVersion;
|
let pypyVersion;
|
||||||
@ -1164,6 +1165,10 @@ function parsePyPyVersion(versionSpec) {
|
|||||||
else {
|
else {
|
||||||
pypyVersion = 'x';
|
pypyVersion = 'x';
|
||||||
}
|
}
|
||||||
|
if (!utils_1.validateVersion(pythonVersion) || !utils_1.validateVersion(pypyVersion)) {
|
||||||
|
core.setFailed("Invalid 'version' property for PyPy. Both Python version and PyPy versions should satisfy SemVer notation. See README for examples and documentation.");
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
pypyVersion: pypyVersion,
|
pypyVersion: pypyVersion,
|
||||||
pythonVersion: pythonVersion
|
pythonVersion: pythonVersion
|
||||||
@ -2316,6 +2321,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const fs = __importStar(__webpack_require__(747));
|
const fs = __importStar(__webpack_require__(747));
|
||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
|
const semver = __importStar(__webpack_require__(876));
|
||||||
exports.IS_WINDOWS = process.platform === 'win32';
|
exports.IS_WINDOWS = process.platform === 'win32';
|
||||||
exports.IS_LINUX = process.platform === 'linux';
|
exports.IS_LINUX = process.platform === 'linux';
|
||||||
/** create Symlinks for downloaded PyPy
|
/** create Symlinks for downloaded PyPy
|
||||||
@ -2334,6 +2340,14 @@ function createSymlinkInFolder(folderPath, sourceName, targetName, setExecutable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.createSymlinkInFolder = createSymlinkInFolder;
|
exports.createSymlinkInFolder = createSymlinkInFolder;
|
||||||
|
function validateVersion(version) {
|
||||||
|
return isNightlyKeyword(version) || Boolean(semver.validRange(version));
|
||||||
|
}
|
||||||
|
exports.validateVersion = validateVersion;
|
||||||
|
function isNightlyKeyword(pypyVersion) {
|
||||||
|
return pypyVersion === 'nightly';
|
||||||
|
}
|
||||||
|
exports.isNightlyKeyword = isNightlyKeyword;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -2766,9 +2780,14 @@ function installPyPy(pypyVersion, pythonVersion, architecture) {
|
|||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let downloadDir;
|
let downloadDir;
|
||||||
const releases = yield getAvailablePyPyVersions();
|
const releases = yield getAvailablePyPyVersions();
|
||||||
|
if (!releases || releases.length === 0) {
|
||||||
|
core.setFailed('No release was found in PyPy version.json');
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
const releaseData = findRelease(releases, pythonVersion, pypyVersion, architecture);
|
const releaseData = findRelease(releases, pythonVersion, pypyVersion, architecture);
|
||||||
if (!releaseData || !releaseData.foundAsset) {
|
if (!releaseData || !releaseData.foundAsset) {
|
||||||
throw new Error(`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`);
|
core.setFailed(`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`);
|
||||||
|
process.exit();
|
||||||
}
|
}
|
||||||
const { foundAsset, resolvedPythonVersion, resolvedPyPyVersion } = releaseData;
|
const { foundAsset, resolvedPythonVersion, resolvedPyPyVersion } = releaseData;
|
||||||
let downloadUrl = `${foundAsset.download_url}`;
|
let downloadUrl = `${foundAsset.download_url}`;
|
||||||
@ -2786,7 +2805,7 @@ function installPyPy(pypyVersion, pythonVersion, architecture) {
|
|||||||
const archiveName = fs.readdirSync(downloadDir)[0];
|
const archiveName = fs.readdirSync(downloadDir)[0];
|
||||||
const toolDir = path.join(downloadDir, archiveName);
|
const toolDir = path.join(downloadDir, archiveName);
|
||||||
let installDir = toolDir;
|
let installDir = toolDir;
|
||||||
if (!isNightlyKeyword(resolvedPyPyVersion)) {
|
if (!utils_1.isNightlyKeyword(resolvedPyPyVersion)) {
|
||||||
installDir = yield tc.cacheDir(toolDir, 'PyPy', resolvedPythonVersion, architecture);
|
installDir = yield tc.cacheDir(toolDir, 'PyPy', resolvedPythonVersion, architecture);
|
||||||
}
|
}
|
||||||
writeExactPyPyVersionFile(installDir, resolvedPyPyVersion);
|
writeExactPyPyVersionFile(installDir, resolvedPyPyVersion);
|
||||||
@ -2803,7 +2822,8 @@ function getAvailablePyPyVersions() {
|
|||||||
const http = new httpm.HttpClient('tool-cache');
|
const http = new httpm.HttpClient('tool-cache');
|
||||||
const response = yield http.getJson(url);
|
const response = yield http.getJson(url);
|
||||||
if (!response.result) {
|
if (!response.result) {
|
||||||
throw new Error(`Unable to retrieve the list of available PyPy versions from '${url}'`);
|
core.setFailed(`Unable to retrieve the list of available PyPy versions from '${url}'`);
|
||||||
|
process.exit();
|
||||||
}
|
}
|
||||||
return response.result;
|
return response.result;
|
||||||
});
|
});
|
||||||
@ -2830,12 +2850,13 @@ function installPip(pythonLocation) {
|
|||||||
}
|
}
|
||||||
function findRelease(releases, pythonVersion, pypyVersion, architecture) {
|
function findRelease(releases, pythonVersion, pypyVersion, architecture) {
|
||||||
const filterReleases = releases.filter(item => {
|
const filterReleases = releases.filter(item => {
|
||||||
const isPythonVersionSatisfies = semver.satisfies(semver.coerce(item.python_version), pythonVersion);
|
const isPythonVersionSatisfied = semver.satisfies(semver.coerce(item.python_version), pythonVersion);
|
||||||
const isPyPyNightly = isNightlyKeyword(pypyVersion) && isNightlyKeyword(item.pypy_version);
|
const isPyPyNightly = utils_1.isNightlyKeyword(pypyVersion) && utils_1.isNightlyKeyword(item.pypy_version);
|
||||||
const isPyPyVersionSatisfies = isPyPyNightly ||
|
const isPyPyVersionSatisfied = isPyPyNightly ||
|
||||||
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
|
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
|
||||||
const isArchExists = item.files.some(file => file.arch === architecture && file.platform === process.platform);
|
const isArchPresent = item.files &&
|
||||||
return isPythonVersionSatisfies && isPyPyVersionSatisfies && isArchExists;
|
item.files.some(file => file.arch === architecture && file.platform === process.platform);
|
||||||
|
return isPythonVersionSatisfied && isPyPyVersionSatisfied && isArchPresent;
|
||||||
});
|
});
|
||||||
if (filterReleases.length === 0) {
|
if (filterReleases.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
@ -2884,9 +2905,6 @@ function getPyPyBinaryPath(installDir) {
|
|||||||
return utils_1.IS_WINDOWS ? installDir : _binDir;
|
return utils_1.IS_WINDOWS ? installDir : _binDir;
|
||||||
}
|
}
|
||||||
exports.getPyPyBinaryPath = getPyPyBinaryPath;
|
exports.getPyPyBinaryPath = getPyPyBinaryPath;
|
||||||
function isNightlyKeyword(pypyVersion) {
|
|
||||||
return pypyVersion === 'nightly';
|
|
||||||
}
|
|
||||||
function pypyVersionToSemantic(versionSpec) {
|
function pypyVersionToSemantic(versionSpec) {
|
||||||
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc))(\d*)/g;
|
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc))(\d*)/g;
|
||||||
return versionSpec.replace(prereleaseVersion, '$1-$2.$3');
|
return versionSpec.replace(prereleaseVersion, '$1-$2.$3');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as pypyInstall from './install-pypy';
|
import * as pypyInstall from './install-pypy';
|
||||||
import {IS_WINDOWS} from './utils';
|
import {IS_WINDOWS, validateVersion} from './utils';
|
||||||
|
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
@ -93,10 +93,12 @@ function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec {
|
|||||||
const versions = versionSpec.split('-').filter(item => !!item);
|
const versions = versionSpec.split('-').filter(item => !!item);
|
||||||
|
|
||||||
if (versions.length < 2) {
|
if (versions.length < 2) {
|
||||||
throw new Error(
|
core.setFailed(
|
||||||
"Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-<python-version>'. See readme for more examples."
|
"Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-<python-version>'. See README for examples and documentation."
|
||||||
);
|
);
|
||||||
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
const pythonVersion = versions[1];
|
const pythonVersion = versions[1];
|
||||||
let pypyVersion: string;
|
let pypyVersion: string;
|
||||||
if (versions.length > 2) {
|
if (versions.length > 2) {
|
||||||
@ -105,6 +107,13 @@ function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec {
|
|||||||
pypyVersion = 'x';
|
pypyVersion = 'x';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!validateVersion(pythonVersion) || !validateVersion(pypyVersion)) {
|
||||||
|
core.setFailed(
|
||||||
|
"Invalid 'version' property for PyPy. Both Python version and PyPy versions should satisfy SemVer notation. See README for examples and documentation."
|
||||||
|
);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pypyVersion: pypyVersion,
|
pypyVersion: pypyVersion,
|
||||||
pythonVersion: pythonVersion
|
pythonVersion: pythonVersion
|
||||||
|
@ -6,7 +6,12 @@ import * as httpm from '@actions/http-client';
|
|||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import {IS_WINDOWS, IPyPyManifestRelease, createSymlinkInFolder} from './utils';
|
import {
|
||||||
|
IS_WINDOWS,
|
||||||
|
IPyPyManifestRelease,
|
||||||
|
createSymlinkInFolder,
|
||||||
|
isNightlyKeyword
|
||||||
|
} from './utils';
|
||||||
|
|
||||||
const PYPY_VERSION_FILE = 'PYPY_VERSION';
|
const PYPY_VERSION_FILE = 'PYPY_VERSION';
|
||||||
|
|
||||||
@ -18,6 +23,11 @@ export async function installPyPy(
|
|||||||
let downloadDir;
|
let downloadDir;
|
||||||
|
|
||||||
const releases = await getAvailablePyPyVersions();
|
const releases = await getAvailablePyPyVersions();
|
||||||
|
if (!releases || releases.length === 0) {
|
||||||
|
core.setFailed('No release was found in PyPy version.json');
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
const releaseData = findRelease(
|
const releaseData = findRelease(
|
||||||
releases,
|
releases,
|
||||||
pythonVersion,
|
pythonVersion,
|
||||||
@ -26,9 +36,10 @@ export async function installPyPy(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!releaseData || !releaseData.foundAsset) {
|
if (!releaseData || !releaseData.foundAsset) {
|
||||||
throw new Error(
|
core.setFailed(
|
||||||
`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`
|
`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`
|
||||||
);
|
);
|
||||||
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
const {foundAsset, resolvedPythonVersion, resolvedPyPyVersion} = releaseData;
|
const {foundAsset, resolvedPythonVersion, resolvedPyPyVersion} = releaseData;
|
||||||
@ -74,9 +85,10 @@ async function getAvailablePyPyVersions() {
|
|||||||
|
|
||||||
const response = await http.getJson<IPyPyManifestRelease[]>(url);
|
const response = await http.getJson<IPyPyManifestRelease[]>(url);
|
||||||
if (!response.result) {
|
if (!response.result) {
|
||||||
throw new Error(
|
core.setFailed(
|
||||||
`Unable to retrieve the list of available PyPy versions from '${url}'`
|
`Unable to retrieve the list of available PyPy versions from '${url}'`
|
||||||
);
|
);
|
||||||
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.result;
|
return response.result;
|
||||||
@ -124,19 +136,21 @@ function findRelease(
|
|||||||
architecture: string
|
architecture: string
|
||||||
) {
|
) {
|
||||||
const filterReleases = releases.filter(item => {
|
const filterReleases = releases.filter(item => {
|
||||||
const isPythonVersionSatisfies = semver.satisfies(
|
const isPythonVersionSatisfied = semver.satisfies(
|
||||||
semver.coerce(item.python_version)!,
|
semver.coerce(item.python_version)!,
|
||||||
pythonVersion
|
pythonVersion
|
||||||
);
|
);
|
||||||
const isPyPyNightly =
|
const isPyPyNightly =
|
||||||
isNightlyKeyword(pypyVersion) && isNightlyKeyword(item.pypy_version);
|
isNightlyKeyword(pypyVersion) && isNightlyKeyword(item.pypy_version);
|
||||||
const isPyPyVersionSatisfies =
|
const isPyPyVersionSatisfied =
|
||||||
isPyPyNightly ||
|
isPyPyNightly ||
|
||||||
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
|
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
|
||||||
const isArchExists = item.files.some(
|
const isArchPresent =
|
||||||
file => file.arch === architecture && file.platform === process.platform
|
item.files &&
|
||||||
);
|
item.files.some(
|
||||||
return isPythonVersionSatisfies && isPyPyVersionSatisfies && isArchExists;
|
file => file.arch === architecture && file.platform === process.platform
|
||||||
|
);
|
||||||
|
return isPythonVersionSatisfied && isPyPyVersionSatisfied && isArchPresent;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (filterReleases.length === 0) {
|
if (filterReleases.length === 0) {
|
||||||
@ -206,10 +220,6 @@ export function getPyPyBinaryPath(installDir: string) {
|
|||||||
return IS_WINDOWS ? installDir : _binDir;
|
return IS_WINDOWS ? installDir : _binDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNightlyKeyword(pypyVersion: string) {
|
|
||||||
return pypyVersion === 'nightly';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pypyVersionToSemantic(versionSpec: string) {
|
export function pypyVersionToSemantic(versionSpec: string) {
|
||||||
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc))(\d*)/g;
|
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc))(\d*)/g;
|
||||||
return versionSpec.replace(prereleaseVersion, '$1-$2.$3');
|
return versionSpec.replace(prereleaseVersion, '$1-$2.$3');
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import * as semver from 'semver';
|
||||||
|
|
||||||
export const IS_WINDOWS = process.platform === 'win32';
|
export const IS_WINDOWS = process.platform === 'win32';
|
||||||
export const IS_LINUX = process.platform === 'linux';
|
export const IS_LINUX = process.platform === 'linux';
|
||||||
@ -40,3 +41,11 @@ export function createSymlinkInFolder(
|
|||||||
fs.chmodSync(targetPath, '755');
|
fs.chmodSync(targetPath, '755');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function validateVersion(version: string) {
|
||||||
|
return isNightlyKeyword(version) || Boolean(semver.validRange(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isNightlyKeyword(pypyVersion: string) {
|
||||||
|
return pypyVersion === 'nightly';
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user