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
- name: Setup PDM
uses: ./
id: setup-pdm
with:
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
run: pdm install -v && pdm info

View File

@ -17,9 +17,9 @@ steps:
- uses: pdm-project/setup-pdm@main
name: Setup PDM
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
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
enable-pep582: true # Enable PEP 582 package loading globally
- name: Install dependencies
@ -28,3 +28,19 @@ steps:
```
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 }}
required: false
version:
description: The version of PDM to install.
required: false
ref:
description: The Ref of GitHub Repository
description: The version of PDM to install, or 'head' to install from the main branch.
required: false
prerelease:
description: Allow prerelease versions to be installed
@ -28,6 +25,15 @@ inputs:
description: "Enable PEP 582 package loading globally."
default: "true"
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:
using: "node16"
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": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"got": "^12.5.2",
"semver": "^7.3.8",
"setup-python": "actions/setup-python"
},

View File

@ -1,19 +1,21 @@
import * as os from 'os'
import { promises as fs } from 'fs'
import path from 'path'
import * as core from '@actions/core'
import * as exec from '@actions/exec'
import { IS_WINDOWS } from 'setup-python/src/utils'
import semParse from 'semver/functions/parse'
import semIntersect from 'semver/ranges/intersects'
import { findPythonVersion } from './utils'
import * as utils from './utils'
const PDM_PYTHON_REQUIRES = '>=3.7'
const GITHUB_REPO = 'https://github.com/pdm-project/pdm.git'
const INSTALL_SCRIPT_URL = 'https://raw.githubusercontent.com/pdm-project/pdm/main/install-pdm.py'
interface InstallOutput {
pdm_version: string;
pdm_bin: string;
install_python_version: string;
install_location: string;
}
function getPep582Path(version: string): string {
const installDir = process.env.pythonLocation || ''
const parsedVersion = semParse(version)!
function getPep582Path(installDir: string, pythonVersion: string): string {
const parsedVersion = semParse(pythonVersion)!
if (IS_WINDOWS) {
return path.resolve(installDir, 'Lib/site-packages/pdm/pep582')
} else {
@ -25,30 +27,33 @@ async function run(): Promise<void> {
const arch = core.getInput('architecture') || os.arch()
const pdmVersion = core.getInput('version')
const pythonVersion = core.getInput('python-version')
const versionCompatible = semIntersect(PDM_PYTHON_REQUIRES, pythonVersion)
const ref = core.getInput('ref')
const pdmPackage = pdmVersion ? `pdm==${pdmVersion}` : ref ? `pdm @ git+${GITHUB_REPO}@${ref}` : 'pdm'
const cmdArgs = ['-m', 'pip', 'install', '-U', pdmPackage]
const cmdArgs = ['-']
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 {
let installedPython = await findPythonVersion(versionCompatible ? pythonVersion : PDM_PYTHON_REQUIRES, arch)
await exec.exec('python', cmdArgs)
await exec.exec('python', cmdArgs, { input: await utils.fetchUrlAsBuffer(INSTALL_SCRIPT_URL) })
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') {
core.exportVariable('PYTHONPATH', getPep582Path(installedPython))
core.exportVariable('PYTHONPATH', getPep582Path(installOutput.install_location, installOutput.install_python_version))
}
if (!versionCompatible) {
installedPython = await 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')
const installedPython = await utils.findPythonVersion(pythonVersion, arch)
if (process.platform === 'linux') {
// See https://github.com/actions/virtual-environments/issues/2803
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')
core.info(`##[add-matcher]${path.join(matchersPath, 'python.json')}`)
} catch (error: any) {

View File

@ -1,12 +1,22 @@
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 { findPyPyVersion } from 'setup-python/src/find-pypy';
function isPyPyVersion(versionSpec: string) {
function isPyPyVersion(versionSpec: string): boolean {
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> {
let pythonVersion = '';
@ -34,3 +44,8 @@ export async function findPythonVersion(version: string, architecture: string):
return installed.version;
}
}
export async function readFile(filePath: string): Promise<string> {
return await fs.readFile(filePath, 'utf8');
}