From 88ffd4d597d830d67a7369dd33dcb72c0958a807 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 21 Jul 2025 21:01:05 +0200 Subject: [PATCH 1/3] Include python version in PyPy python-version output (#1110) --- dist/setup/index.js | 2 +- src/find-pypy.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index f8c5d4e72..a6cebf56e 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -95875,7 +95875,7 @@ function findPyPyVersion(versionSpec, architecture, updateEnvironment, checkLate core.addPath(pythonLocation); core.addPath(_binDir); } - core.setOutput('python-version', 'pypy' + resolvedPyPyVersion); + core.setOutput('python-version', `pypy${resolvedPythonVersion}-${resolvedPyPyVersion}`); core.setOutput('python-path', pythonPath); return { resolvedPyPyVersion, resolvedPythonVersion }; }); diff --git a/src/find-pypy.ts b/src/find-pypy.ts index 9807878a9..d15ebf60f 100644 --- a/src/find-pypy.ts +++ b/src/find-pypy.ts @@ -96,7 +96,10 @@ export async function findPyPyVersion( core.addPath(pythonLocation); core.addPath(_binDir); } - core.setOutput('python-version', 'pypy' + resolvedPyPyVersion); + core.setOutput( + 'python-version', + `pypy${resolvedPythonVersion}-${resolvedPyPyVersion}` + ); core.setOutput('python-path', pythonPath); return {resolvedPyPyVersion, resolvedPythonVersion}; From 3c6f142cc0036d53007e92fa1e327564a4cfb7aa Mon Sep 17 00:00:00 2001 From: priya-kinthali <147703874+priya-kinthali@users.noreply.github.com> Date: Thu, 24 Jul 2025 00:02:04 +0530 Subject: [PATCH 2/3] update documentation (#1156) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8dc6d08fd..c3f16cf62 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,8 @@ steps: >The requirements file format allows for specifying dependency versions using logical operators (for example chardet>=3.0.4) or specifying dependencies without any versions. In this case the pip install -r requirements.txt command will always try to install the latest available package version. To be sure that the cache will be used, please stick to a specific dependency version and update it manually if necessary. +>The `setup-python` action does not handle authentication for pip when installing packages from private repositories. For help, refer [pip’s VCS support documentation](https://pip.pypa.io/en/stable/topics/vcs-support/) or visit the [pip repository](https://github.com/pypa/pip). + See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poetry` in the section: [Caching packages](docs/advanced-usage.md#caching-packages) of the [Advanced usage](docs/advanced-usage.md) guide. ## Advanced usage From 36da51d563b70a972897150555bb025096d65565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aram=C3=ADs=20Segovia?= Date: Thu, 24 Jul 2025 18:40:39 -0400 Subject: [PATCH 3/3] Add version parsing from Pipfile (#1067) * feature: add version parsing from Pipfile * Update utils.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/utils.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/utils.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore: update dist/setup/index.js --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../workflows/test-python-freethreaded.yml | 80 ++++++++++++++ .github/workflows/test-python.yml | 100 ++++++++++++++++++ __tests__/utils.test.ts | 39 +++++++ dist/setup/index.js | 41 ++++++- docs/advanced-usage.md | 9 ++ src/utils.ts | 42 +++++++- 6 files changed, 308 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-python-freethreaded.yml b/.github/workflows/test-python-freethreaded.yml index 39e69a474..94f783e23 100644 --- a/.github/workflows/test-python-freethreaded.yml +++ b/.github/workflows/test-python-freethreaded.yml @@ -242,6 +242,86 @@ jobs: with: python-version-file: .tool-versions + setup-versions-from-pipfile-with-python_version: + name: Setup ${{ matrix.python }} ${{ matrix.os }} Pipfile + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + [ + macos-latest, + windows-latest, + ubuntu-22.04, + ubuntu-22.04-arm, + macos-13, + ubuntu-latest, + ubuntu-24.04-arm + ] + python: [3.13t, 3.14t-dev] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: build-version-file ${{ matrix.python }} + run: | + echo '[requires] + python_version = "${{ matrix.python }}" + ' > Pipfile + + - name: setup-python ${{ matrix.python }} + id: setup-python + uses: ./ + with: + python-version-file: Pipfile + + - name: Check python-path + run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' + shell: bash + + - name: Run simple code + run: python -c 'import math; print(math.factorial(5))' + + setup-versions-from-pipfile-with-python_full_version: + name: Setup ${{ matrix.python }} ${{ matrix.os }} .tool-versions file + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + [ + macos-latest, + windows-latest, + ubuntu-22.04, + ubuntu-22.04-arm, + macos-13, + ubuntu-latest, + ubuntu-24.04-arm + ] + python: [3.13.0t, 3.13.1t, 3.13.2t, 3.14t-dev] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: build-version-file ${{ matrix.python }} + run: | + echo '[requires] + python_full_version = "${{ matrix.python }}" + ' > Pipfile + + - name: setup-python ${{ matrix.python }} + id: setup-python + uses: ./ + with: + python-version-file: Pipfile + + - name: Check python-path + run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' + shell: bash + + - name: Run simple code + run: python -c 'import math; print(math.factorial(5))' + setup-pre-release-version-from-manifest: name: Setup 3.14.0-alpha.6 ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index d89646f30..02a9a99f3 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -284,6 +284,106 @@ jobs: with: python-version-file: .tool-versions + setup-versions-from-pipfile-with-python_version: + name: Setup ${{ matrix.python }} ${{ matrix.os }} Pipfile with python_version + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + [ + macos-latest, + windows-latest, + ubuntu-22.04, + ubuntu-22.04-arm, + macos-13, + ubuntu-latest, + ubuntu-24.04-arm + ] + python: [3.9.13, 3.10.11, 3.11.9, 3.13.2] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: build-version-file ${{ matrix.python }} + run: | + echo '[requires] + python_version = "${{ matrix.python }}" + ' > Pipfile + + - name: setup-python ${{ matrix.python }} + id: setup-python + uses: ./ + with: + python-version-file: Pipfile + + - name: Check python-path + run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' + shell: bash + + - name: Validate version + run: | + $pythonVersion = (python --version) + if ("Python ${{ matrix.python }}".replace("==", "") -ne "$pythonVersion"){ + Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}" + exit 1 + } + $pythonVersion + shell: pwsh + + - name: Run simple code + run: python -c 'import math; print(math.factorial(5))' + + setup-versions-from-pipfile-with-python_full_version: + name: Setup ${{ matrix.python }} ${{ matrix.os }} Pipfile with python_full_version + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + [ + macos-latest, + windows-latest, + ubuntu-22.04, + ubuntu-22.04-arm, + macos-13, + ubuntu-latest, + ubuntu-24.04-arm + ] + python: [3.9.13, 3.10.11, 3.11.9, 3.13.2] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: build-version-file ${{ matrix.python }} + run: | + echo '[requires] + python_full_version = "${{ matrix.python }}" + ' > Pipfile + + - name: setup-python ${{ matrix.python }} + id: setup-python + uses: ./ + with: + python-version-file: Pipfile + + - name: Check python-path + run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' + shell: bash + + - name: Validate version + run: | + $pythonVersion = (python --version) + if ("Python ${{ matrix.python }}".replace("==", "") -ne "$pythonVersion"){ + Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}" + exit 1 + } + $pythonVersion + shell: pwsh + + - name: Run simple code + run: python -c 'import math; print(math.factorial(5))' + setup-pre-release-version-from-manifest: name: Setup 3.14.0-alpha.6 ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/__tests__/utils.test.ts b/__tests__/utils.test.ts index 009749c6b..2cbfa8132 100644 --- a/__tests__/utils.test.ts +++ b/__tests__/utils.test.ts @@ -12,6 +12,7 @@ import { getVersionInputFromFile, getVersionsInputFromPlainFile, getVersionInputFromTomlFile, + getVersionInputFromPipfileFile, getNextPageUrl, isGhes, IS_WINDOWS, @@ -244,6 +245,44 @@ describe('Version from file test', () => { expect(_fn(toolVersionFilePath)).toEqual(['3.14t-dev']); } ); + + it.each([getVersionInputFromPipfileFile, getVersionInputFromFile])( + 'Version from python_version in Pipfile', + async _fn => { + await io.mkdirP(tempDir); + const pythonVersionFileName = 'Pipfile'; + const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName); + const pythonVersion = '3.13'; + const pythonVersionFileContent = `[requires]\npython_version = "${pythonVersion}"`; + fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent); + expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]); + } + ); + + it.each([getVersionInputFromPipfileFile, getVersionInputFromFile])( + 'Version from python_full_version in Pipfile', + async _fn => { + await io.mkdirP(tempDir); + const pythonVersionFileName = 'Pipfile'; + const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName); + const pythonVersion = '3.13.0'; + const pythonVersionFileContent = `[requires]\npython_full_version = "${pythonVersion}"`; + fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent); + expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]); + } + ); + + it.each([getVersionInputFromPipfileFile, getVersionInputFromFile])( + 'Pipfile undefined version', + async _fn => { + await io.mkdirP(tempDir); + const pythonVersionFileName = 'Pipfile'; + const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName); + const pythonVersionFileContent = ``; + fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent); + expect(_fn(pythonVersionFilePath)).toEqual([]); + } + ); }); describe('getNextPageUrl', () => { diff --git a/dist/setup/index.js b/dist/setup/index.js index a6cebf56e..70aac4738 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -97067,7 +97067,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getDownloadFileName = exports.getNextPageUrl = exports.getBinaryDirectory = exports.getVersionInputFromFile = exports.getVersionInputFromToolVersions = exports.getVersionsInputFromPlainFile = exports.getVersionInputFromTomlFile = exports.getOSInfo = exports.getLinuxInfo = exports.logWarning = exports.isCacheFeatureAvailable = exports.isGhes = exports.validatePythonVersionFormatForPyPy = exports.writeExactPyPyVersionFile = exports.readExactPyPyVersionFile = exports.getPyPyVersionFromPath = exports.isNightlyKeyword = exports.validateVersion = exports.createSymlinkInFolder = exports.WINDOWS_PLATFORMS = exports.WINDOWS_ARCHS = exports.IS_MAC = exports.IS_LINUX = exports.IS_WINDOWS = void 0; +exports.getDownloadFileName = exports.getNextPageUrl = exports.getBinaryDirectory = exports.getVersionInputFromFile = exports.getVersionInputFromPipfileFile = exports.getVersionInputFromToolVersions = exports.getVersionsInputFromPlainFile = exports.getVersionInputFromTomlFile = exports.getOSInfo = exports.getLinuxInfo = exports.logWarning = exports.isCacheFeatureAvailable = exports.isGhes = exports.validatePythonVersionFormatForPyPy = exports.writeExactPyPyVersionFile = exports.readExactPyPyVersionFile = exports.getPyPyVersionFromPath = exports.isNightlyKeyword = exports.validateVersion = exports.createSymlinkInFolder = exports.WINDOWS_PLATFORMS = exports.WINDOWS_ARCHS = exports.IS_MAC = exports.IS_LINUX = exports.IS_WINDOWS = void 0; /* eslint no-unsafe-finally: "off" */ const cache = __importStar(__nccwpck_require__(5116)); const core = __importStar(__nccwpck_require__(7484)); @@ -97337,7 +97337,41 @@ function getVersionInputFromToolVersions(versionFile) { } exports.getVersionInputFromToolVersions = getVersionInputFromToolVersions; /** - * Python version extracted from a plain, .tool-versions or TOML file. + * Python version extracted from the Pipfile file. + */ +function getVersionInputFromPipfileFile(versionFile) { + core.debug(`Trying to resolve version from ${versionFile}`); + if (!fs_1.default.existsSync(versionFile)) { + core.warning(`File ${versionFile} does not exist.`); + return []; + } + let pipfileFile = fs_1.default.readFileSync(versionFile, 'utf8'); + // Normalize the line endings in the pipfileFile + pipfileFile = pipfileFile.replace(/\r\n/g, '\n'); + const pipfileConfig = toml.parse(pipfileFile); + const keys = ['requires']; + if (!('requires' in pipfileConfig)) { + core.warning(`No Python version found in ${versionFile}`); + return []; + } + if ('python_full_version' in pipfileConfig['requires']) { + // specifies a full python version + keys.push('python_full_version'); + } + else { + keys.push('python_version'); + } + const versions = []; + const version = extractValue(pipfileConfig, keys); + if (version !== undefined) { + versions.push(version); + } + core.info(`Extracted ${versions} from ${versionFile}`); + return versions; +} +exports.getVersionInputFromPipfileFile = getVersionInputFromPipfileFile; +/** + * Python version extracted from a plain, .tool-versions, Pipfile or TOML file. */ function getVersionInputFromFile(versionFile) { if (versionFile.endsWith('.toml')) { @@ -97346,6 +97380,9 @@ function getVersionInputFromFile(versionFile) { else if (versionFile.match('.tool-versions')) { return getVersionInputFromToolVersions(versionFile); } + else if (versionFile.match('Pipfile')) { + return getVersionInputFromPipfileFile(versionFile); + } else { return getVersionsInputFromPlainFile(versionFile); } diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 96524823e..188fa9d65 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -310,6 +310,15 @@ steps: - run: python my_script.py ``` +```yaml +steps: +- uses: actions/checkout@v4 +- uses: actions/setup-python@v5 + with: + python-version-file: 'Pipfile' # Read python version from a file Pipfile +- run: python my_script.py +``` + ## Check latest version The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific `Python or PyPy` version is always used. diff --git a/src/utils.ts b/src/utils.ts index f39006d98..d7be47463 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -325,14 +325,54 @@ export function getVersionInputFromToolVersions(versionFile: string): string[] { return []; } } + +/** + * Python version extracted from the Pipfile file. + */ +export function getVersionInputFromPipfileFile(versionFile: string): string[] { + core.debug(`Trying to resolve version from ${versionFile}`); + + if (!fs.existsSync(versionFile)) { + core.warning(`File ${versionFile} does not exist.`); + return []; + } + let pipfileFile = fs.readFileSync(versionFile, 'utf8'); + // Normalize the line endings in the pipfileFile + pipfileFile = pipfileFile.replace(/\r\n/g, '\n'); + + const pipfileConfig = toml.parse(pipfileFile); + const keys = ['requires']; + + if (!('requires' in pipfileConfig)) { + core.warning(`No Python version found in ${versionFile}`); + return []; + } + if ('python_full_version' in (pipfileConfig['requires'] as toml.JsonMap)) { + // specifies a full python version + keys.push('python_full_version'); + } else { + keys.push('python_version'); + } + const versions = []; + const version = extractValue(pipfileConfig, keys); + if (version !== undefined) { + versions.push(version); + } + + core.info(`Extracted ${versions} from ${versionFile}`); + return versions; +} + /** - * Python version extracted from a plain, .tool-versions or TOML file. + * Python version extracted from a plain, .tool-versions, Pipfile or TOML file. */ export function getVersionInputFromFile(versionFile: string): string[] { if (versionFile.endsWith('.toml')) { return getVersionInputFromTomlFile(versionFile); } else if (versionFile.match('.tool-versions')) { return getVersionInputFromToolVersions(versionFile); + } else if (versionFile.match('Pipfile')) { + return getVersionInputFromPipfileFile(versionFile); } else { return getVersionsInputFromPlainFile(versionFile); } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy