Skip to content

Commit e9c40fb

Browse files
Add support for pip-version (#1129)
* Add pip-version input * Update workflow files * Add documentation * Update workflow files
1 parent 5fa0ee6 commit e9c40fb

File tree

7 files changed

+179
-0
lines changed

7 files changed

+179
-0
lines changed

.github/workflows/e2e-cache-freethreaded.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,60 @@ jobs:
162162
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
163163
- name: Install dependencies
164164
run: pipenv install requests
165+
166+
python-pip-dependencies-caching-with-pip-version:
167+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
168+
runs-on: ${{ matrix.os }}
169+
strategy:
170+
fail-fast: false
171+
matrix:
172+
os:
173+
[
174+
ubuntu-latest,
175+
ubuntu-22.04,
176+
ubuntu-24.04-arm,
177+
ubuntu-22.04-arm,
178+
windows-latest,
179+
macos-latest,
180+
macos-13
181+
]
182+
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
183+
steps:
184+
- uses: actions/checkout@v4
185+
- name: Setup Python
186+
uses: ./
187+
with:
188+
python-version: ${{ matrix.python-version }}
189+
cache: 'pip'
190+
pip-version: '25.0.1'
191+
- name: Install dependencies
192+
run: pip install numpy pandas requests
193+
194+
python-pip-dependencies-caching-path-with-pip-version:
195+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
196+
runs-on: ${{ matrix.os }}
197+
strategy:
198+
fail-fast: false
199+
matrix:
200+
os:
201+
[
202+
ubuntu-latest,
203+
ubuntu-22.04,
204+
ubuntu-24.04-arm,
205+
ubuntu-22.04-arm,
206+
windows-latest,
207+
macos-latest,
208+
macos-13
209+
]
210+
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
211+
steps:
212+
- uses: actions/checkout@v4
213+
- name: Setup Python
214+
uses: ./
215+
with:
216+
python-version: ${{ matrix.python-version }}
217+
cache: 'pip'
218+
cache-dependency-path: __tests__/data/requirements.txt
219+
pip-version: '25.0.1'
220+
- name: Install dependencies
221+
run: pip install numpy pandas requests

.github/workflows/e2e-cache.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,60 @@ jobs:
249249
}
250250
- name: Run Python Script
251251
run: pipenv run python test-pipenv.py
252+
253+
python-pip-dependencies-caching-with-pip-version:
254+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
255+
runs-on: ${{ matrix.os }}
256+
strategy:
257+
fail-fast: false
258+
matrix:
259+
os:
260+
[
261+
ubuntu-latest,
262+
ubuntu-24.04-arm,
263+
ubuntu-22.04,
264+
ubuntu-22.04-arm,
265+
windows-latest,
266+
macos-latest,
267+
macos-13
268+
]
269+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
270+
steps:
271+
- uses: actions/checkout@v4
272+
- name: Setup Python
273+
uses: ./
274+
with:
275+
python-version: ${{ matrix.python-version }}
276+
cache: 'pip'
277+
pip-version: '25.0.1'
278+
- name: Install dependencies
279+
run: pip install numpy pandas requests
280+
281+
python-pip-dependencies-caching-path-with-pip-version:
282+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
283+
runs-on: ${{ matrix.os }}
284+
strategy:
285+
fail-fast: false
286+
matrix:
287+
os:
288+
[
289+
ubuntu-latest,
290+
ubuntu-24.04-arm,
291+
ubuntu-22.04,
292+
ubuntu-22.04-arm,
293+
windows-latest,
294+
macos-latest,
295+
macos-13
296+
]
297+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
298+
steps:
299+
- uses: actions/checkout@v4
300+
- name: Setup Python
301+
uses: ./
302+
with:
303+
python-version: ${{ matrix.python-version }}
304+
cache: 'pip'
305+
cache-dependency-path: __tests__/data/requirements.txt
306+
pip-version: '25.0.1'
307+
- name: Install dependencies
308+
run: pip install numpy pandas requests

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet
108108
- [Using `setup-python` with a self-hosted runner](docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner)
109109
- [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes)
110110
- [Allow pre-releases](docs/advanced-usage.md#allow-pre-releases)
111+
- [Using the pip-version input](docs/advanced-usage.md#using-the-pip-version-input)
111112

112113
## Recommended permissions
113114

action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ inputs:
2929
freethreaded:
3030
description: "When 'true', use the freethreaded version of Python."
3131
default: false
32+
pip-version:
33+
description: "Used to specify the version of pip to install with the Python. Supported format: major[.minor][.patch]."
3234
outputs:
3335
python-version:
3436
description: "The installed Python or PyPy version. Useful when given a version range as input."

dist/setup/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95990,6 +95990,7 @@ const semver = __importStar(__nccwpck_require__(2088));
9599095990
const installer = __importStar(__nccwpck_require__(1919));
9599195991
const core = __importStar(__nccwpck_require__(7484));
9599295992
const tc = __importStar(__nccwpck_require__(3472));
95993+
const exec = __importStar(__nccwpck_require__(5236));
9599395994
// Python has "scripts" or "bin" directories where command-line tools that come with packages are installed.
9599495995
// This is where pip is, along with anything that pip installs.
9599595996
// There is a separate directory for `pip install --user`.
@@ -96010,6 +96011,20 @@ function binDir(installDir) {
9601096011
return path.join(installDir, 'bin');
9601196012
}
9601296013
}
96014+
function installPip(pythonLocation) {
96015+
return __awaiter(this, void 0, void 0, function* () {
96016+
const pipVersion = core.getInput('pip-version');
96017+
// Validate pip-version format: major[.minor][.patch]
96018+
const versionRegex = /^\d+(\.\d+)?(\.\d+)?$/;
96019+
if (pipVersion && !versionRegex.test(pipVersion)) {
96020+
throw new Error(`Invalid pip-version "${pipVersion}". Please specify a version in the format major[.minor][.patch].`);
96021+
}
96022+
if (pipVersion) {
96023+
core.info(`pip-version input is specified. Installing pip version ${pipVersion}`);
96024+
yield exec.exec(`${pythonLocation}/python -m pip install --upgrade pip==${pipVersion} --disable-pip-version-check --no-warn-script-location`);
96025+
}
96026+
});
96027+
}
9601396028
function useCpythonVersion(version, architecture, updateEnvironment, checkLatest, allowPreReleases, freethreaded) {
9601496029
return __awaiter(this, void 0, void 0, function* () {
9601596030
var _a;
@@ -96105,6 +96120,8 @@ function useCpythonVersion(version, architecture, updateEnvironment, checkLatest
9610596120
}
9610696121
core.setOutput('python-version', pythonVersion);
9610796122
core.setOutput('python-path', pythonPath);
96123+
const binaryPath = utils_1.IS_WINDOWS ? installDir : _binDir;
96124+
yield installPip(binaryPath);
9610896125
return { impl: 'CPython', version: pythonVersion };
9610996126
});
9611096127
}

docs/advanced-usage.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
- [macOS](advanced-usage.md#macos)
2323
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
2424
- [Allow pre-releases](advanced-usage.md#allow-pre-releases)
25+
- [Using the pip-version input](advanced-usage.md#using-the-pip-version-input)
2526

2627
## Using the `python-version` input
2728

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

647+
## Using the pip-version input
648+
649+
The `pip-version` input allows you to specify the desired version of **Pip** to use with the standard Python version.
650+
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).
651+
652+
```yaml
653+
steps:
654+
- uses: actions/checkout@v4
655+
- name: Set up Python
656+
uses: actions/setup-python@v5
657+
with:
658+
python-version: '3.13'
659+
pip-version: '25.0.1'
660+
- name: Display Pip version
661+
run: pip --version
662+
```
663+
> The `pip-version` input is supported only with standard Python versions. It is not available when using PyPy or GraalPy.
664+
665+
> 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/).

src/find-python.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as installer from './install-python';
88

99
import * as core from '@actions/core';
1010
import * as tc from '@actions/tool-cache';
11+
import * as exec from '@actions/exec';
1112

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

34+
async function installPip(pythonLocation: string) {
35+
const pipVersion = core.getInput('pip-version');
36+
37+
// Validate pip-version format: major[.minor][.patch]
38+
const versionRegex = /^\d+(\.\d+)?(\.\d+)?$/;
39+
if (pipVersion && !versionRegex.test(pipVersion)) {
40+
throw new Error(
41+
`Invalid pip-version "${pipVersion}". Please specify a version in the format major[.minor][.patch].`
42+
);
43+
}
44+
45+
if (pipVersion) {
46+
core.info(
47+
`pip-version input is specified. Installing pip version ${pipVersion}`
48+
);
49+
await exec.exec(
50+
`${pythonLocation}/python -m pip install --upgrade pip==${pipVersion} --disable-pip-version-check --no-warn-script-location`
51+
);
52+
}
53+
}
54+
3355
export async function useCpythonVersion(
3456
version: string,
3557
architecture: string,
@@ -179,6 +201,9 @@ export async function useCpythonVersion(
179201
core.setOutput('python-version', pythonVersion);
180202
core.setOutput('python-path', pythonPath);
181203

204+
const binaryPath = IS_WINDOWS ? installDir : _binDir;
205+
await installPip(binaryPath);
206+
182207
return {impl: 'CPython', version: pythonVersion};
183208
}
184209

0 commit comments

Comments
 (0)