feat: Use the install script to install PDM in isolated environment (#21)

This commit is contained in:
Frost Ming 2022-10-21 10:19:30 +08:00 committed by GitHub
parent 21f59457b4
commit 1c39d42ed6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 8074 additions and 579 deletions

View File

@ -14,9 +14,17 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Setup PDM - name: Setup PDM
uses: ./ uses: ./
id: setup-pdm
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Check output
run: |
echo ${{ steps.setup-pdm.outputs.pdm-bin }}
echo ${{ steps.setup-pdm.outputs.pdm-version }}
echo ${{ steps.setup-pdm.outputs.python-path }}
echo ${{ steps.setup-pdm.outputs.python-version }}
- name: Install dependencies - name: Install dependencies
run: pdm install -v && pdm info run: pdm install -v && pdm info

View File

@ -17,9 +17,9 @@ steps:
- uses: pdm-project/setup-pdm@main - uses: pdm-project/setup-pdm@main
name: Setup PDM name: Setup PDM
with: with:
python-version: 3.8 # Version range or exact version of a Python version to use, the same as actions/setup-python python-version: 3.9 # Version range or exact version of a Python version to use, the same as actions/setup-python
architecture: x64 # The target architecture (x86, x64) of the Python interpreter. the same as actions/setup-python architecture: x64 # The target architecture (x86, x64) of the Python interpreter. the same as actions/setup-python
version: 1.4.0 # The version of PDM to install. Leave it as empty to use the latest version from PyPI version: 1.4.0 # The version of PDM to install. Leave it as empty to use the latest version from PyPI, or 'head' to use the latest version from GitHub
prerelease: true # Allow prerelease versions to be installed prerelease: true # Allow prerelease versions to be installed
enable-pep582: true # Enable PEP 582 package loading globally enable-pep582: true # Enable PEP 582 package loading globally
- name: Install dependencies - name: Install dependencies
@ -28,3 +28,19 @@ steps:
``` ```
You don't need `actions/setup-python` actually. You don't need `actions/setup-python` actually.
## Action Outputs
This action also exposes the following outputs:
```yaml
outputs:
python-version:
description: "The installed Python or PyPy version. Useful when given a version range as input."
python-path:
description: "The absolute path to the Python or PyPy executable."
pdm-version:
description: "The installed PDM version."
pdm-bin:
description: "The absolute path to the PDM executable."
```

View File

@ -15,10 +15,7 @@ inputs:
default: ${{ github.token }} default: ${{ github.token }}
required: false required: false
version: version:
description: The version of PDM to install. description: The version of PDM to install, or 'head' to install from the main branch.
required: false
ref:
description: The Ref of GitHub Repository
required: false required: false
prerelease: prerelease:
description: Allow prerelease versions to be installed description: Allow prerelease versions to be installed
@ -28,6 +25,15 @@ inputs:
description: "Enable PEP 582 package loading globally." description: "Enable PEP 582 package loading globally."
default: "true" default: "true"
required: false required: false
outputs:
python-version:
description: "The installed Python or PyPy version. Useful when given a version range as input."
python-path:
description: "The absolute path to the Python or PyPy executable."
pdm-version:
description: "The installed PDM version."
pdm-bin:
description: "The absolute path to the PDM executable."
runs: runs:
using: "node16" using: "node16"
main: "dist/setup-pdm.js" main: "dist/setup-pdm.js"

8542
dist/setup-pdm.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
"dependencies": { "dependencies": {
"@actions/core": "^1.10.0", "@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1", "@actions/exec": "^1.1.1",
"got": "^12.5.2",
"semver": "^7.3.8", "semver": "^7.3.8",
"setup-python": "actions/setup-python" "setup-python": "actions/setup-python"
}, },

View File

@ -1,19 +1,21 @@
import * as os from 'os' import * as os from 'os'
import { promises as fs } from 'fs'
import path from 'path' import path from 'path'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as exec from '@actions/exec' import * as exec from '@actions/exec'
import { IS_WINDOWS } from 'setup-python/src/utils' import { IS_WINDOWS } from 'setup-python/src/utils'
import semParse from 'semver/functions/parse' import semParse from 'semver/functions/parse'
import semIntersect from 'semver/ranges/intersects' import * as utils from './utils'
import { findPythonVersion } from './utils'
const PDM_PYTHON_REQUIRES = '>=3.7' const INSTALL_SCRIPT_URL = 'https://raw.githubusercontent.com/pdm-project/pdm/main/install-pdm.py'
const GITHUB_REPO = 'https://github.com/pdm-project/pdm.git' interface InstallOutput {
pdm_version: string;
pdm_bin: string;
install_python_version: string;
install_location: string;
}
function getPep582Path(version: string): string { function getPep582Path(installDir: string, pythonVersion: string): string {
const installDir = process.env.pythonLocation || '' const parsedVersion = semParse(pythonVersion)!
const parsedVersion = semParse(version)!
if (IS_WINDOWS) { if (IS_WINDOWS) {
return path.resolve(installDir, 'Lib/site-packages/pdm/pep582') return path.resolve(installDir, 'Lib/site-packages/pdm/pep582')
} else { } else {
@ -25,30 +27,33 @@ async function run(): Promise<void> {
const arch = core.getInput('architecture') || os.arch() const arch = core.getInput('architecture') || os.arch()
const pdmVersion = core.getInput('version') const pdmVersion = core.getInput('version')
const pythonVersion = core.getInput('python-version') const pythonVersion = core.getInput('python-version')
const versionCompatible = semIntersect(PDM_PYTHON_REQUIRES, pythonVersion) const cmdArgs = ['-']
const ref = core.getInput('ref')
const pdmPackage = pdmVersion ? `pdm==${pdmVersion}` : ref ? `pdm @ git+${GITHUB_REPO}@${ref}` : 'pdm'
const cmdArgs = ['-m', 'pip', 'install', '-U', pdmPackage]
if (core.getInput('prerelease') === 'true') { if (core.getInput('prerelease') === 'true') {
cmdArgs.push('--pre') cmdArgs.push('--prerelease')
} }
if (pdmVersion) {
cmdArgs.push('--version', pdmVersion)
}
cmdArgs.push('-o', 'install-output.json')
// Use the default python version installed with the runner
try { try {
let installedPython = await findPythonVersion(versionCompatible ? pythonVersion : PDM_PYTHON_REQUIRES, arch) await exec.exec('python', cmdArgs, { input: await utils.fetchUrlAsBuffer(INSTALL_SCRIPT_URL) })
await exec.exec('python', cmdArgs) const installOutput: InstallOutput = JSON.parse(await utils.readFile('install-output.json'))
core.debug(`Install output: ${installOutput}`)
core.setOutput('pdm-version', installOutput.pdm_version)
core.setOutput('pdm-bin', path.join(installOutput.install_location, installOutput.pdm_bin))
core.addPath(path.dirname(installOutput.pdm_bin))
if (core.getInput('enable-pep582') === 'true') { if (core.getInput('enable-pep582') === 'true') {
core.exportVariable('PYTHONPATH', getPep582Path(installedPython)) core.exportVariable('PYTHONPATH', getPep582Path(installOutput.install_location, installOutput.install_python_version))
} }
if (!versionCompatible) {
installedPython = await findPythonVersion(pythonVersion, arch) const installedPython = await utils.findPythonVersion(pythonVersion, arch)
}
const pythonBin = path.join(process.env.pythonLocation as string, IS_WINDOWS ? 'python.exe' : 'bin/python').replace(/\\/g, '/')
await fs.writeFile('.pdm.toml', `[python]\npath="${pythonBin}"\n`)
const { stdout: pdmVersionOutput } = await exec.getExecOutput('pdm --version')
if (process.platform === 'linux') { if (process.platform === 'linux') {
// See https://github.com/actions/virtual-environments/issues/2803 // See https://github.com/actions/virtual-environments/issues/2803
core.exportVariable('LD_PRELOAD', '/lib/x86_64-linux-gnu/libgcc_s.so.1') core.exportVariable('LD_PRELOAD', '/lib/x86_64-linux-gnu/libgcc_s.so.1')
} }
core.info(`Successfully setup ${pdmVersionOutput} with Python ${installedPython}`) core.info(`Successfully setup ${installOutput.pdm_version} with Python ${installedPython}`)
const matchersPath = path.join(__dirname, '..', '.github') const matchersPath = path.join(__dirname, '..', '.github')
core.info(`##[add-matcher]${path.join(matchersPath, 'python.json')}`) core.info(`##[add-matcher]${path.join(matchersPath, 'python.json')}`)
} catch (error: any) { } catch (error: any) {

View File

@ -1,12 +1,22 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import got from 'got';
import { promises as fs } from 'fs';
import { useCpythonVersion } from 'setup-python/src/find-python'; import { useCpythonVersion } from 'setup-python/src/find-python';
import { findPyPyVersion } from 'setup-python/src/find-pypy'; import { findPyPyVersion } from 'setup-python/src/find-pypy';
function isPyPyVersion(versionSpec: string) { function isPyPyVersion(versionSpec: string): boolean {
return versionSpec.startsWith('pypy'); return versionSpec.startsWith('pypy');
} }
export async function fetchUrlAsBuffer(url: string): Promise<Buffer> {
const response = await got(url);
if (!response.ok) {
throw new Error(`Failed to fetch ${url}`);
}
return Buffer.from(response.body);
}
export async function findPythonVersion(version: string, architecture: string): Promise<string> { export async function findPythonVersion(version: string, architecture: string): Promise<string> {
let pythonVersion = ''; let pythonVersion = '';
@ -34,3 +44,8 @@ export async function findPythonVersion(version: string, architecture: string):
return installed.version; return installed.version;
} }
} }
export async function readFile(filePath: string): Promise<string> {
return await fs.readFile(filePath, 'utf8');
}