Skip to content

Commit 2e3e4b1

Browse files
gowridurgad“gowridurgad”
andauthored
Add support for pip-install input (#1201)
* Add pip-install input * Improve error message * Logic update --------- Co-authored-by: “gowridurgad” <“[email protected]>
1 parent 4267e28 commit 2e3e4b1

File tree

7 files changed

+163
-0
lines changed

7 files changed

+163
-0
lines changed

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,56 @@ jobs:
219219
pip-version: '25.0.1'
220220
- name: Install dependencies
221221
run: pip install numpy pandas requests
222+
223+
python-pip-dependencies-caching-with-pip-install:
224+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
225+
runs-on: ${{ matrix.os }}
226+
strategy:
227+
fail-fast: false
228+
matrix:
229+
os:
230+
[
231+
ubuntu-latest,
232+
ubuntu-22.04,
233+
ubuntu-24.04-arm,
234+
ubuntu-22.04-arm,
235+
windows-latest,
236+
macos-latest,
237+
macos-13
238+
]
239+
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
240+
steps:
241+
- uses: actions/checkout@v5
242+
- name: Setup Python
243+
uses: ./
244+
with:
245+
python-version: ${{ matrix.python-version }}
246+
cache: 'pip'
247+
pip-install: numpy pandas requests
248+
249+
python-pip-dependencies-caching-path-with-pip-install:
250+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
251+
runs-on: ${{ matrix.os }}
252+
strategy:
253+
fail-fast: false
254+
matrix:
255+
os:
256+
[
257+
ubuntu-latest,
258+
ubuntu-22.04,
259+
ubuntu-24.04-arm,
260+
ubuntu-22.04-arm,
261+
windows-latest,
262+
macos-latest,
263+
macos-13
264+
]
265+
python-version: [3.13.0t, 3.13.1t, 3.13.2t]
266+
steps:
267+
- uses: actions/checkout@v5
268+
- name: Setup Python
269+
uses: ./
270+
with:
271+
python-version: ${{ matrix.python-version }}
272+
cache: 'pip'
273+
cache-dependency-path: __tests__/data/requirements.txt
274+
pip-install: numpy pandas requests

.github/workflows/e2e-cache.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,56 @@ jobs:
311311
pip-version: '25.0.1'
312312
- name: Install dependencies
313313
run: pip install numpy pandas requests
314+
315+
python-pip-dependencies-caching-with-pip-install:
316+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
317+
runs-on: ${{ matrix.os }}
318+
strategy:
319+
fail-fast: false
320+
matrix:
321+
os:
322+
[
323+
ubuntu-latest,
324+
ubuntu-24.04-arm,
325+
ubuntu-22.04,
326+
ubuntu-22.04-arm,
327+
windows-latest,
328+
macos-latest,
329+
macos-13
330+
]
331+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
332+
steps:
333+
- uses: actions/checkout@v5
334+
- name: Setup Python
335+
uses: ./
336+
with:
337+
python-version: ${{ matrix.python-version }}
338+
cache: 'pip'
339+
pip-install: numpy pandas requests
340+
341+
python-pip-dependencies-caching-path-with-pip-install:
342+
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
343+
runs-on: ${{ matrix.os }}
344+
strategy:
345+
fail-fast: false
346+
matrix:
347+
os:
348+
[
349+
ubuntu-latest,
350+
ubuntu-24.04-arm,
351+
ubuntu-22.04,
352+
ubuntu-22.04-arm,
353+
windows-latest,
354+
macos-latest,
355+
macos-13
356+
]
357+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
358+
steps:
359+
- uses: actions/checkout@v5
360+
- name: Setup Python
361+
uses: ./
362+
with:
363+
python-version: ${{ matrix.python-version }}
364+
cache: 'pip'
365+
cache-dependency-path: __tests__/data/requirements.txt
366+
pip-install: numpy pandas requests

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet
118118
- [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes)
119119
- [Allow pre-releases](docs/advanced-usage.md#allow-pre-releases)
120120
- [Using the pip-version input](docs/advanced-usage.md#using-the-pip-version-input)
121+
- [Using the pip-install input](docs/advanced-usage.md#using-the-pip-install-input)
121122

122123
## Recommended permissions
123124

action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ inputs:
3131
default: false
3232
pip-version:
3333
description: "Used to specify the version of pip to install with the Python. Supported format: major[.minor][.patch]."
34+
pip-install:
35+
description: "Used to specify the packages to install with pip after setting up Python. Can be a requirements file or package names."
3436
outputs:
3537
python-version:
3638
description: "The installed Python or PyPy version. Useful when given a version range as input."

dist/setup/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97944,12 +97944,26 @@ const os = __importStar(__nccwpck_require__(857));
9794497944
const fs_1 = __importDefault(__nccwpck_require__(9896));
9794597945
const cache_factory_1 = __nccwpck_require__(665);
9794697946
const utils_1 = __nccwpck_require__(1798);
97947+
const exec_1 = __nccwpck_require__(5236);
9794797948
function isPyPyVersion(versionSpec) {
9794897949
return versionSpec.startsWith('pypy');
9794997950
}
9795097951
function isGraalPyVersion(versionSpec) {
9795197952
return versionSpec.startsWith('graalpy');
9795297953
}
97954+
function installPipPackages(pipInstall) {
97955+
return __awaiter(this, void 0, void 0, function* () {
97956+
core.info(`Installing pip packages: ${pipInstall}`);
97957+
try {
97958+
const installArgs = pipInstall.trim().split(/\s+/);
97959+
yield (0, exec_1.exec)('python', ['-m', 'pip', 'install', ...installArgs]);
97960+
core.info('Successfully installed pip packages');
97961+
}
97962+
catch (error) {
97963+
core.setFailed(`Failed to install pip packages from "${pipInstall}". Please verify that the package names, versions, or requirements files provided are correct and installable, that the specified packages and versions can be resolved from PyPI or the configured package index, and that your network connection is stable and allows access to the package index.`);
97964+
}
97965+
});
97966+
}
9795397967
function cacheDependencies(cache, pythonVersion) {
9795497968
return __awaiter(this, void 0, void 0, function* () {
9795597969
const cacheDependencyPath = core.getInput('cache-dependency-path') || undefined;
@@ -98038,6 +98052,10 @@ function run() {
9803898052
if (cache && (0, utils_1.isCacheFeatureAvailable)()) {
9803998053
yield cacheDependencies(cache, pythonVersion);
9804098054
}
98055+
const pipInstall = core.getInput('pip-install');
98056+
if (pipInstall) {
98057+
yield installPipPackages(pipInstall);
98058+
}
9804198059
}
9804298060
else {
9804398061
core.warning('The `python-version` input is not set. The version of Python currently in `PATH` will be used.');

docs/advanced-usage.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
2424
- [Allow pre-releases](advanced-usage.md#allow-pre-releases)
2525
- [Using the pip-version input](advanced-usage.md#using-the-pip-version-input)
26+
- [Using the pip-install input](advanced-usage.md#using-the-pip-install-input)
2627

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

@@ -672,3 +673,20 @@ The version of Pip should be specified in the format `major`, `major.minor`, or
672673
> The `pip-version` input is supported only with standard Python versions. It is not available when using PyPy or GraalPy.
673674

674675
> 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/).
676+
677+
## Using the pip-install input
678+
679+
The `pip-install` input allows you to install dependencies as part of the Python setup step.
680+
681+
682+
```yaml
683+
steps:
684+
- uses: actions/checkout@v5
685+
- name: Set up Python
686+
uses: actions/setup-python@v6
687+
with:
688+
python-version: '3.13'
689+
pip-install: -r requirements.txt
690+
```
691+
> Note: This feature is intended for standard pip-based dependency installations.
692+
For complex workflows, or alternative package managers (e.g., poetry, pipenv), we recommend using separate steps to maintain clarity and flexibility.

src/setup-python.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
getVersionInputFromFile,
1414
getVersionsInputFromPlainFile
1515
} from './utils';
16+
import {exec} from '@actions/exec';
1617

1718
function isPyPyVersion(versionSpec: string) {
1819
return versionSpec.startsWith('pypy');
@@ -22,6 +23,19 @@ function isGraalPyVersion(versionSpec: string) {
2223
return versionSpec.startsWith('graalpy');
2324
}
2425

26+
async function installPipPackages(pipInstall: string) {
27+
core.info(`Installing pip packages: ${pipInstall}`);
28+
try {
29+
const installArgs = pipInstall.trim().split(/\s+/);
30+
await exec('python', ['-m', 'pip', 'install', ...installArgs]);
31+
core.info('Successfully installed pip packages');
32+
} catch (error) {
33+
core.setFailed(
34+
`Failed to install pip packages from "${pipInstall}". Please verify that the package names, versions, or requirements files provided are correct and installable, that the specified packages and versions can be resolved from PyPI or the configured package index, and that your network connection is stable and allows access to the package index.`
35+
);
36+
}
37+
}
38+
2539
async function cacheDependencies(cache: string, pythonVersion: string) {
2640
const cacheDependencyPath =
2741
core.getInput('cache-dependency-path') || undefined;
@@ -145,6 +159,10 @@ async function run() {
145159
if (cache && isCacheFeatureAvailable()) {
146160
await cacheDependencies(cache, pythonVersion);
147161
}
162+
const pipInstall = core.getInput('pip-install');
163+
if (pipInstall) {
164+
await installPipPackages(pipInstall);
165+
}
148166
} else {
149167
core.warning(
150168
'The `python-version` input is not set. The version of Python currently in `PATH` will be used.'

0 commit comments

Comments
 (0)