From fa589f774a5ec5cb5590d357a35e3a07e454df06 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Sun, 4 Dec 2022 22:51:04 +0100 Subject: [PATCH] add support to install multiple python versions --- .github/workflows/test-pypy.yml | 43 +++++++++++++++++++ .github/workflows/test-python.yml | 26 +++++++++++- dist/setup/index.js | 43 +++++++++++-------- src/setup-python.ts | 68 +++++++++++++++++-------------- 4 files changed, 131 insertions(+), 49 deletions(-) diff --git a/.github/workflows/test-pypy.yml b/.github/workflows/test-pypy.yml index de9ba6b7..7cd1bc5e 100644 --- a/.github/workflows/test-pypy.yml +++ b/.github/workflows/test-pypy.yml @@ -123,4 +123,47 @@ jobs: EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe ${EXECUTABLE} --version + shell: bash + + setup-pypy-multiple-versions: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + steps: + - uses: actions/checkout@v3 + - name: Setup PyPy and check latest + uses: ./ + with: + python-version: | + pypy-3.7-v7.3.x + pypy3.9-nightly + pypy3.8 + check-latest: true + - name: PyPy and Python version + run: python --version + + - name: Run simple code + run: python -c 'import math; print(math.factorial(5))' + + - name: Assert PyPy is running + run: | + import platform + assert platform.python_implementation().lower() == "pypy" + shell: python + + - name: Assert expected binaries (or symlinks) are present + run: | + EXECUTABLE="pypy-3.7-v7.3.x" + EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name + EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe + ${EXECUTABLE} --version + shell: bash + - name: Assert expected binaries (or symlinks) are present + run: | + EXECUTABLE='pypy3.8' + 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 \ No newline at end of file diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 921449fb..c1800c2b 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -190,8 +190,30 @@ jobs: - name: Validate version run: | $pythonVersion = (python --version) - if ("$pythonVersion" -NotMatch "${{ matrix.python }}"){ - Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}" + if ("$pythonVersion" -NotMatch "${{ matrix.python-version }}"){ + Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python-version }}" + exit 1 + } + $pythonVersion + shell: pwsh + setup-python-multiple-versions: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + steps: + - uses: actions/checkout@v3 + - name: Setup Python and check latest + uses: ./ + with: + python-version: ${{ matrix.python-version }} + check-latest: true + - name: Validate version + run: | + $pythonVersion = (python --version) + if ("$pythonVersion" -NotMatch "${{ matrix.python-version }}"){ + Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python-version }}" exit 1 } $pythonVersion diff --git a/dist/setup/index.js b/dist/setup/index.js index d9282071..619656fc 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -66797,12 +66797,12 @@ function cacheDependencies(cache, pythonVersion) { }); } function resolveVersionInput() { - let version = core.getInput('python-version'); + let version = core.getMultilineInput('python-version'); let versionFile = core.getInput('python-version-file'); - if (version && versionFile) { + if (version.length && versionFile) { core.warning('Both python-version and python-version-file inputs are specified, only python-version will be used.'); } - if (version) { + if (version.length) { return version; } if (versionFile) { @@ -66834,21 +66834,30 @@ function run() { } core.debug(`Python is expected to be installed into ${process.env['RUNNER_TOOL_CACHE']}`); try { - const version = resolveVersionInput(); + let versions; + const resolvedVersionInput = resolveVersionInput(); const checkLatest = core.getBooleanInput('check-latest'); - if (version) { - let pythonVersion; - const arch = core.getInput('architecture') || os.arch(); - const updateEnvironment = core.getBooleanInput('update-environment'); - if (isPyPyVersion(version)) { - const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment, checkLatest); - pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; - core.info(`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`); - } - else { - const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment, checkLatest); - pythonVersion = installed.version; - core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); + if (Array.isArray(resolvedVersionInput)) { + versions = resolvedVersionInput; + } + else { + versions = [resolvedVersionInput]; + } + if (versions.length) { + let pythonVersion = ''; + for (const version of versions) { + const arch = core.getInput('architecture') || os.arch(); + const updateEnvironment = core.getBooleanInput('update-environment'); + if (isPyPyVersion(version)) { + const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment, checkLatest); + pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; + core.info(`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`); + } + else { + const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment, checkLatest); + pythonVersion = installed.version; + core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); + } } const cache = core.getInput('cache'); if (cache && utils_1.isCacheFeatureAvailable()) { diff --git a/src/setup-python.ts b/src/setup-python.ts index d6e6bdaf..0f3af6de 100644 --- a/src/setup-python.ts +++ b/src/setup-python.ts @@ -22,17 +22,17 @@ async function cacheDependencies(cache: string, pythonVersion: string) { await cacheDistributor.restoreCache(); } -function resolveVersionInput(): string { - let version = core.getInput('python-version'); +function resolveVersionInput(): string | string[] { + let version: string | string[] = core.getMultilineInput('python-version'); let versionFile = core.getInput('python-version-file'); - if (version && versionFile) { + if (version.length && versionFile) { core.warning( 'Both python-version and python-version-file inputs are specified, only python-version will be used.' ); } - if (version) { + if (version.length) { return version; } @@ -75,35 +75,43 @@ async function run() { `Python is expected to be installed into ${process.env['RUNNER_TOOL_CACHE']}` ); try { - const version = resolveVersionInput(); + let versions: string[]; + const resolvedVersionInput = resolveVersionInput(); const checkLatest = core.getBooleanInput('check-latest'); - if (version) { - let pythonVersion: string; - const arch: string = core.getInput('architecture') || os.arch(); - const updateEnvironment = core.getBooleanInput('update-environment'); - if (isPyPyVersion(version)) { - const installed = await finderPyPy.findPyPyVersion( - version, - arch, - updateEnvironment, - checkLatest - ); - pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; - core.info( - `Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})` - ); - } else { - const installed = await finder.useCpythonVersion( - version, - arch, - updateEnvironment, - checkLatest - ); - pythonVersion = installed.version; - core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); - } + if (Array.isArray(resolvedVersionInput)) { + versions = resolvedVersionInput as string[]; + } else { + versions = [resolvedVersionInput as string]; + } + if (versions.length) { + let pythonVersion = ''; + for (const version of versions) { + const arch: string = core.getInput('architecture') || os.arch(); + const updateEnvironment = core.getBooleanInput('update-environment'); + if (isPyPyVersion(version)) { + const installed = await finderPyPy.findPyPyVersion( + version, + arch, + updateEnvironment, + checkLatest + ); + pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; + core.info( + `Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})` + ); + } else { + const installed = await finder.useCpythonVersion( + version, + arch, + updateEnvironment, + checkLatest + ); + pythonVersion = installed.version; + core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); + } + } const cache = core.getInput('cache'); if (cache && isCacheFeatureAvailable()) { await cacheDependencies(cache, pythonVersion);