Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/e2e-cache-freethreaded.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,60 @@ jobs:
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies
run: pipenv install requests

python-pip-dependencies-caching-with-pip-version:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-22.04,
ubuntu-24.04-arm,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
pip-version: '25.0.1'
- name: Install dependencies
run: pip install numpy pandas requests

python-pip-dependencies-caching-path-with-pip-version:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-22.04,
ubuntu-24.04-arm,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: __tests__/data/requirements.txt
pip-version: '25.0.1'
- name: Install dependencies
run: pip install numpy pandas requests
57 changes: 57 additions & 0 deletions .github/workflows/e2e-cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,60 @@ jobs:
}
- name: Run Python Script
run: pipenv run python test-pipenv.py

python-pip-dependencies-caching-with-pip-version:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
pip-version: '25.0.1'
- name: Install dependencies
run: pip install numpy pandas requests

python-pip-dependencies-caching-path-with-pip-version:
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
ubuntu-latest,
ubuntu-24.04-arm,
ubuntu-22.04,
ubuntu-22.04-arm,
windows-latest,
macos-latest,
macos-13
]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: ./
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: __tests__/data/requirements.txt
pip-version: '25.0.1'
- name: Install dependencies
run: pip install numpy pandas requests
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet
- [Using `setup-python` with a self-hosted runner](docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner)
- [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes)
- [Allow pre-releases](docs/advanced-usage.md#allow-pre-releases)
- [Using the pip-version input](docs/advanced-usage.md#using-the-pip-version-input)

## Recommended permissions

Expand Down
2 changes: 2 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ inputs:
freethreaded:
description: "When 'true', use the freethreaded version of Python."
default: false
pip-version:
description: "Used to specify the version of pip to install with the Python. Supported format: major[.minor][.patch]."
outputs:
python-version:
description: "The installed Python or PyPy version. Useful when given a version range as input."
Expand Down
17 changes: 17 additions & 0 deletions dist/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -95990,6 +95990,7 @@ const semver = __importStar(__nccwpck_require__(2088));
const installer = __importStar(__nccwpck_require__(1919));
const core = __importStar(__nccwpck_require__(7484));
const tc = __importStar(__nccwpck_require__(3472));
const exec = __importStar(__nccwpck_require__(5236));
// Python has "scripts" or "bin" directories where command-line tools that come with packages are installed.
// This is where pip is, along with anything that pip installs.
// There is a separate directory for `pip install --user`.
Expand All @@ -96010,6 +96011,20 @@ function binDir(installDir) {
return path.join(installDir, 'bin');
}
}
function installPip(pythonLocation) {
return __awaiter(this, void 0, void 0, function* () {
const pipVersion = core.getInput('pip-version');
// Validate pip-version format: major[.minor][.patch]
const versionRegex = /^\d+(\.\d+)?(\.\d+)?$/;
if (pipVersion && !versionRegex.test(pipVersion)) {
throw new Error(`Invalid pip-version "${pipVersion}". Please specify a version in the format major[.minor][.patch].`);
}
if (pipVersion) {
core.info(`pip-version input is specified. Installing pip version ${pipVersion}`);
yield exec.exec(`${pythonLocation}/python -m pip install --upgrade pip==${pipVersion} --disable-pip-version-check --no-warn-script-location`);
}
});
}
function useCpythonVersion(version, architecture, updateEnvironment, checkLatest, allowPreReleases, freethreaded) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
Expand Down Expand Up @@ -96105,6 +96120,8 @@ function useCpythonVersion(version, architecture, updateEnvironment, checkLatest
}
core.setOutput('python-version', pythonVersion);
core.setOutput('python-path', pythonPath);
const binaryPath = utils_1.IS_WINDOWS ? installDir : _binDir;
yield installPip(binaryPath);
return { impl: 'CPython', version: pythonVersion };
});
}
Expand Down
20 changes: 20 additions & 0 deletions docs/advanced-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- [macOS](advanced-usage.md#macos)
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
- [Allow pre-releases](advanced-usage.md#allow-pre-releases)
- [Using the pip-version input](advanced-usage.md#using-the-pip-version-input)

## Using the `python-version` input

Expand Down Expand Up @@ -643,3 +644,22 @@ jobs:
- run: pipx run nox --error-on-missing-interpreters -s tests-${{ matrix.python_version }}
```

## Using the pip-version input

The `pip-version` input allows you to specify the desired version of **Pip** to use with the standard Python version.
The version of Pip should be specified in the format `major`, `major.minor`, or `major.minor.patch` (for example: 25, 25.1, or 25.0.1).

```yaml
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
pip-version: '25.0.1'
- name: Display Pip version
run: pip --version
```
> The `pip-version` input is supported only with standard Python versions. It is not available when using PyPy or GraalPy.

> Using a specific or outdated version of pip may result in compatibility or security issues and can cause job failures. For best practices and guidance, refer to the official [pip documentation](https://pip.pypa.io/en/stable/).
25 changes: 25 additions & 0 deletions src/find-python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as installer from './install-python';

import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec';

// Python has "scripts" or "bin" directories where command-line tools that come with packages are installed.
// This is where pip is, along with anything that pip installs.
Expand All @@ -30,6 +31,27 @@ function binDir(installDir: string): string {
}
}

async function installPip(pythonLocation: string) {
const pipVersion = core.getInput('pip-version');

// Validate pip-version format: major[.minor][.patch]
const versionRegex = /^\d+(\.\d+)?(\.\d+)?$/;
if (pipVersion && !versionRegex.test(pipVersion)) {
throw new Error(
`Invalid pip-version "${pipVersion}". Please specify a version in the format major[.minor][.patch].`
);
}

if (pipVersion) {
core.info(
`pip-version input is specified. Installing pip version ${pipVersion}`
);
await exec.exec(
`${pythonLocation}/python -m pip install --upgrade pip==${pipVersion} --disable-pip-version-check --no-warn-script-location`
);
}
}

export async function useCpythonVersion(
version: string,
architecture: string,
Expand Down Expand Up @@ -179,6 +201,9 @@ export async function useCpythonVersion(
core.setOutput('python-version', pythonVersion);
core.setOutput('python-path', pythonPath);

const binaryPath = IS_WINDOWS ? installDir : _binDir;
await installPip(binaryPath);

return {impl: 'CPython', version: pythonVersion};
}

Expand Down
Loading