8000 Install multiple python versions (#567) · erikni/setup-python@5ccb29d · GitHub
[go: up one dir, main page]

Skip to content

Commit 5ccb29d

Browse files
Install multiple python versions (actions#567)
1 parent c3e0339 commit 5ccb29d

File tree

5 files changed

+190
-57
lines changed
  • dist/setup
  • docs
  • src
  • 5 files changed

    +190
    -57
    lines changed

    .github/workflows/test-pypy.yml

    Lines changed: 42 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -124,4 +124,46 @@ jobs:
    124124
    EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
    125125
    EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
    126< 8000 /code>126
    ${EXECUTABLE} --version
    127+
    shell: bash
    128+
    129+
    setup-pypy-multiple-versions:
    130+
    runs-on: ${{ matrix.os }}
    131+
    strategy:
    132+
    fail-fast: false
    133+
    matrix:
    134+
    os: [ubuntu-latest, windows-latest, macos-latest]
    135+
    steps:
    136+
    - uses: actions/checkout@v3
    137+
    - name: Setup PyPy and check latest
    138+
    uses: ./
    139+
    with:
    140+
    python-version: |
    141+
    pypy-3.7-v7.3.x
    142+
    pypy3.8
    143+
    check-latest: true
    144+
    - name: PyPy and Python version
    145+
    run: python --version
    146+
    147+
    - name: Run simple code
    148+
    run: python -c 'import math; print(math.factorial(5))'
    149+
    150+
    - name: Assert PyPy is running
    151+
    run: |
    152+
    import platform
    153+
    assert platform.python_implementation().lower() == "pypy"
    154+
    shell: python
    155+
    156+
    - name: Assert expected binaries (or symlinks) are present
    157+
    run: |
    158+
    EXECUTABLE="pypy-3.7-v7.3.x"
    159+
    EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
    160+
    EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
    161+
    ${EXECUTABLE} --version
    162+
    shell: bash
    163+
    - name: Assert expected binaries (or symlinks) are present
    164+
    run: |
    165+
    EXECUTABLE='pypy3.8'
    166+
    EXECUTABLE=${EXECUTABLE/pypy-/pypy} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name
    167+
    EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe
    168+
    ${EXECUTABLE} --version
    127169
    shell: bash

    .github/workflows/test-python.yml

    Lines changed: 29 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -191,8 +191,35 @@ jobs:
    191191
    - name: Validate version
    192192
    run: |
    193193
    $pythonVersion = (python --version)
    194-
    if ("$pythonVersion" -NotMatch "${{ matrix.python }}"){
    195-
    Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}"
    194+
    if ("$pythonVersion" -NotMatch "${{ matrix.python-version }}"){
    195+
    Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python-version }}"
    196+
    exit 1
    197+
    }
    198+
    $pythonVersion
    199+
    shell: pwsh
    200+
    201+
    setup-python-multiple-python-versions:
    202+
    runs-on: ${{ matrix.os }}
    203+
    strategy:
    204+
    fail-fast: false
    205+
    matrix:
    206+
    os: [ubuntu-latest, windows-latest, macos-latest]
    207+
    steps:
    208+
    - uses: actions/checkout@v3
    209+
    - name: Setup Python and check latest
    210+
    uses: ./
    211+
    with:
    212+
    python-version: |
    213+
    3.7
    214+
    3.8
    215+
    3.9
    216+
    3.10
    217+
    check-latest: true
    218+
    - name: Validate version
    219+
    run: |
    220+
    $pythonVersion = (python --version)
    221+
    if ("$pythonVersion" -NotMatch "3.10"){
    222+
    Write-Host "The current version is $pythonVersion; expected version is 3.10"
    196223
    exit 1
    197224
    }
    198225
    $pythonVersion

    dist/setup/index.js

    Lines changed: 25 additions & 21 deletions
    Original file line numberDiff line numberDiff line change
    @@ -66867,31 +66867,31 @@ function cacheDependencies(cache, pythonVersion) {
    6686766867
    });
    6686866868
    }
    6686966869
    function resolveVersionInput() {
    66870-
    let version = core.getInput('python-version');
    66870+
    let versions = core.getMultilineInput('python-version');
    6687166871
    let versionFile = core.getInput('python-version-file');
    66872-
    if (version && versionFile) {
    66872+
    if (versions.length && versionFile) {
    6687366873
    core.warning('Both python-version and python-version-file inputs are specified, only python-version will be used.');
    6687466874
    }
    66875-
    if (version) {
    66876-
    return version;
    66875+
    if (versions.length) {
    66876+
    return versions;
    6687766877
    }
    6687866878
    if (versionFile) {
    6687966879
    if (!fs_1.default.existsSync(versionFile)) {
    6688066880
    throw new Error(`The specified python version file at: ${versionFile} doesn't exist.`);
    6688166881
    }
    66882-
    version = fs_1.default.readFileSync(versionFile, 'utf8');
    66882+
    const version = fs_1.default.readFileSync(versionFile, 'utf8');
    6688366883
    core.info(`Resolved ${versionFile} as ${version}`);
    66884-
    return version;
    66884+
    return [version];
    6688566885
    }
    6688666886
    utils_1.logWarning("Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '.python-version' file.");
    6688766887
    versionFile = '.python-version';
    6688866888
    if (fs_1.default.existsSync(versionFile)) {
    66889-
    version = fs_1.default.readFileSync(versionFile, 'utf8');
    66889+
    const version = fs_1.default.readFileSync(versionFile, 'utf8');
    6689066890
    core.info(`Resolved ${versionFile} as ${version}`);
    66891-
    return version;
    66891+
    return [version];
    6689266892
    }
    6689366893
    utils_1.logWarning(`${versionFile} doesn't exist.`);
    66894-
    return version;
    66894+
    return versions;
    6689566895
    }
    6689666896
    function run() {
    6689766897
    var _a;
    @@ -66904,22 +66904,26 @@ function run() {
    6690466904
    }
    6690566905
    core.debug(`Python is expected to be installed into ${process.env['RUNNER_TOOL_CACHE']}`);
    6690666906
    try {
    66907-
    const version = resolveVersionInput();
    66907+
    const versions = resolveVersionInput();
    6690866908
    const checkLatest = core.getBooleanInput('check-latest');
    66909-
    if (version) {
    66910-
    let pythonVersion;
    66909+
    if (versions.length) {
    66910+
    let pythonVersion = '';
    6691166911
    const arch = core.getInput('architecture') || os.arch();
    6691266912
    const updateEnvironment = core.getBooleanInput('update-environment');
    66913-
    if (isPyPyVersion(version)) {
    66914-
    const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment, checkLatest);
    66915-
    pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`;
    66916-
    core.info(`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`);
    66917-
    }
    66918-
    else {
    66919-
    const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment, checkLatest);
    66920-
    pythonVersion = installed.version;
    66921-
    core.info(`Successfully set up ${installed.impl} (${pythonVersion})`);
    66913+
    core.startGroup('Installed versions');
    66914+
    for (const version of versions) {
    66915+
    if (isPyPyVersion(version)) {
    66916+
    const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment, checkLatest);
    66917+
    pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`;
    66918+
    core.info(`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`);
    66919+
    }
    66920+
    else {
    66921+
    const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment, checkLatest);
    66922+
    pythonVersion = installed.version;
    66923+
    core.info(`Successfully set up ${installed.impl} (${pythonVersion})`);
    66924+
    }
    6692266925
    }
    66926+
    core.endGroup();
    6692366927
    const cache = core.getInput('cache');
    6692466928
    if (cache && utils_1.isCacheFeatureAvailable()) {
    6692566929
    yield cacheDependencies(cache, pythonVersion);

    docs/advanced-usage.md

    Lines changed: 57 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -2,6 +2,7 @@
    22
    - [Using the python-version input](advanced-usage.md#using-the-python-version-input)
    33
    - [Specifying a Python version](advanced-usage.md#specifying-a-python-version)
    44
    - [Specifying a PyPy version](advanced-usage.md#specifying-a-pypy-version)
    5+
    - [Specifying multiple Python and PyPy versions](advanced-usage.md#specifying-multiple-python/pypy-version)
    56
    - [Matrix Testing](advanced-usage.md#matrix-testing)
    67
    - [Using the python-version-file input](advanced-usage.md#using-the-python-version-file-input)
    78
    - [Check latest version](advanced-usage.md#check-latest-version)
    @@ -132,6 +133,62 @@ jobs:
    132133
    ```
    133134
    More details on PyPy syntax can be found in the [Available versions of PyPy](#pypy) section.
    134135

    136+
    ### Specifying multiple Python/PyPy version
    137+
    The python-version input can get multiple python/pypy versions. The last specified version will be used as a default one.
    138+
    139+
    Download and set up multiple Python versions:
    140+
    141+
    ```yaml
    142+
    jobs:
    143+
    build:
    144+
    runs-on: ubuntu-latest
    145+
    steps:
    146+
    - uses: actions/checkout@v3
    147+
    - uses: actions/setup-python@v4
    148+
    with:
    149+
    python-version: |
    150+
    3.8
    151+
    3.9
    152+
    3.10
    153+
    - run: python my_script.py
    154+
    ```
    155+
    156+
    Download and set up multiple PyPy versions:
    157+
    158+
    ```yaml
    159+
    jobs:
    160+
    build:
    161+
    runs-on: ubuntu-latest
    162+
    steps:
    163+
    - uses: actions/checkout@v3
    164+
    - uses: actions/setup-python@v4
    165+
    with:
    166+
    python-version: |
    167+
    pypy-3.7-v7.3.x
    168+
    pypy3.9-nightly
    169+
    pypy3.8
    170+
    - run: python my_script.py
    171+
    ```
    172+
    173+
    Download and set up multiple Python/PyPy versions:
    174+
    175+
    ```yaml
    176+
    jobs:
    177+
    build:
    178+
    runs-on: ubuntu-latest
    179+
    steps:
    180+
    - uses: actions/checkout@v3
    181+
    - uses: actions/setup-python@v4
    182+
    with:
    183+
    python-version: |
    184+
    3.8
    185+
    3.9
    186+
    pypy3.9-nightly
    187+
    pypy3.8
    188+
    3.10
    189+
    - run: python my_script.py
    190+
    ```
    191+
    135192
    ### Matrix Testing
    136193
    137194
    Using `setup-python` it's possible to use [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of Python or PyPy:

    src/setup-python.ts

    Lines changed: 37 additions & 34 deletions
    Original file line numberDiff line numberDiff line change
    @@ -22,18 +22,18 @@ async function cacheDependencies(cache: string, pythonVersion: string) {
    2222
    await cacheDistributor.restoreCache();
    2323
    }
    2424

    25-
    function resolveVersionInput(): string {
    26-
    let version = core.getInput('python-version');
    25+
    function resolveVersionInput() {
    26+
    let versions = core.getMultilineInput('python-version');
    2727
    let versionFile = core.getInput('python-version-file');
    2828

    29-
    if (version && versionFile) {
    29+
    if (versions.length && versionFile) {
    3030
    core.warning(
    3131
    'Both python-version and python-version-file inputs are specified, only python-version will be used.'
    3232
    );
    3333
    }
    3434

    35-
    if (version) {
    36-
    return version;
    35+
    if (versions.length) {
    36+
    return versions;
    3737
    }
    3838

    3939
    if (versionFile) {
    @@ -42,24 +42,24 @@ function resolveVersionInput(): string {
    4242
    `The specified python version file at: ${versionFile} doesn't exist.`
    4343
    );
    4444
    }
    45-
    version = fs.readFileSync(versionFile, 'utf8');
    45+
    const version = fs.readFileSync(versionFile, 'utf8');
    4646
    core.info(`Resolved ${versionFile} as ${version}`);
    47-
    return version;
    47+
    return [version];
    4848
    }
    4949

    5050
    logWarning(
    5151
    "Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '.python-version' file."
    5252
    );
    5353
    versionFile = '.python-version';
    5454
    if (fs.existsSync(versionFile)) {
    55-
    version = fs.readFileSync(versionFile, 'utf8');
    55+
    const version = fs.readFileSync(versionFile, 'utf8');
    5656
    core.info(`Resolved ${versionFile} as ${version}`);
    57-
    return version;
    57+
    return [version];
    5858
    }
    5959

    6060
    logWarning(`${versionFile} doesn't exist.`);
    6161

    62-
    return version;
    62+
    return versions;
    6363
    }
    6464

    6565
    async function run() {
    @@ -75,35 +75,38 @@ async function run() {
    7575
    `Python is expected to be installed into ${process.env['RUNNER_TOOL_CACHE']}`
    7676
    );
    7777
    try {
    78-
    const version = resolveVersionInput();
    78+
    const versions = resolveVersionInput();
    7979
    const checkLatest = core.getBooleanInput('check-latest');
    8080

    81-
    if (version) {
    82-
    let pythonVersi 10000 on: string;
    81+
    if (versions.length) {
    82+
    let pythonVersion = '';
    8383
    const arch: string = core.getInput('architecture') || os.arch();
    8484
    const updateEnvironment = core.getBooleanInput('update-environment');
    85-
    if (isPyPyVersion(version)) {
    86-
    const installed = await finderPyPy.findPyPyVersion(
    87-
    version,
    88-
    arch,
    89-
    updateEnvironment,
    90-
    checkLatest
    91-
    );
    92-
    pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`;
    93-
    core.info(
    94-
    `Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`
    95-
    );
    96-
    } else {
    97-
    const installed = await finder.useCpythonVersion(
    98-
    version,
    99-
    arch,
    100-
    updateEnvironment,
    101-
    checkLatest
    102-
    );
    103-
    pythonVersion = installed.version;
    104-
    core.info(`Successfully set up ${installed.impl} (${pythonVersion})`);
    85+
    core.startGroup('Installed versions');
    86+
    for (const version of versions) {
    87+
    if (isPyPyVersion(version)) {
    88+
    const installed = await finderPyPy.findPyPyVersion(
    89+
    version,
    90+
    arch,
    91+
    updateEnvironment,
    92+
    checkLatest
    93+
    );
    94+
    pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`;
    95+
    core.info(
    96+
    `Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`
    97+
    );
    98+
    } else {
    99+
    const installed = await finder.useCpythonVersion(
    100+
    version,
    101+
    arch,
    102+
    updateEnvironment,
    103+
    checkLatest
    104+
    );
    105+
    pythonVersion = installed.version;
    106+
    core.info(`Successfully set up ${installed.impl} (${pythonVersion})`);
    107+
    }
    105108
    }
    106-
    109+
    core.endGroup();
    107110
    const cache = core.getInput('cache');
    108111
    if (cache && isCacheFeatureAvailable()) {
    109112
    await cacheDependencies(cache, pythonVersion);

    0 commit comments

    Comments
     (0)
    0