Compare commits

..
3 changed files with 200 additions and 155 deletions
+42 -3
View File
@@ -73,9 +73,6 @@ jobs:
set -e
which pnpm
which pnpx
case "$PNPM_HOME" in
''|*node_modules*) echo "PNPM_HOME must be set outside node_modules"; exit 1 ;;
esac
actual="$(pnpm --version)"
echo "pnpm --version: ${actual}"
if [ "${actual}" != "${REQUIRED}" ]; then
@@ -425,3 +422,45 @@ jobs:
exit 1
fi
shell: bash
windows_dest_spaces:
name: 'Windows destination with spaces (${{ matrix.version }} / standalone=${{ matrix.standalone }})'
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include:
- version: '10.33.0'
standalone: false
- version: '11.25.0'
standalone: true
- version: '12.3.4'
standalone: false
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: pnpm
uses: ./
with:
version: ${{ matrix.version }}
standalone: ${{ matrix.standalone }}
dest: '${{ runner.temp }}/pnpm setup & tools'
- name: Verify PowerShell and bin_dest use the requested version
shell: pwsh
env:
EXPECTED_VERSION: ${{ matrix.version }}
BIN_DEST: ${{ steps.pnpm.outputs.bin_dest }}
run: |
$actual = pnpm --version
if ($LASTEXITCODE -ne 0 -or $actual -ne $env:EXPECTED_VERSION) {
throw "Expected $env:EXPECTED_VERSION on PATH, got $actual"
}
$command = Get-Command pnpm
$executable = Join-Path $env:BIN_DEST $command.Name
$actual = & $executable --version
if ($LASTEXITCODE -ne 0 -or $actual -ne $env:EXPECTED_VERSION) {
throw "Expected $env:EXPECTED_VERSION via bin_dest, got $actual"
}
$pnpx = Get-Command pnpx -ErrorAction Stop
if ((Split-Path -Parent $pnpx.Source) -ne $env:BIN_DEST) {
throw "pnpx resolves to $($pnpx.Source), expected under $env:BIN_DEST"
}
+136 -136
View File
File diff suppressed because one or more lines are too long
+21 -15
View File
@@ -1,4 +1,5 @@
import { addPath, exportVariable } from '@actions/core'
import { exec } from '@actions/exec'
import { spawn } from 'child_process'
import { rm, writeFile, mkdir, symlink } from 'fs/promises'
import { readFileSync, existsSync } from 'fs'
@@ -72,12 +73,14 @@ export async function runSelfInstaller(inputs: Inputs): Promise<SelfInstallerRes
return { exitCode: npmExitCode, binDest: path.join(dest, 'node_modules', '.bin') }
}
const bootstrapBinDir = standalone && process.platform === 'win32'
const pnpmHome = standalone && process.platform === 'win32'
? path.join(dest, 'node_modules', '@pnpm', 'exe')
: path.join(dest, 'node_modules', '.bin')
const pnpmHome = path.join(dest, 'pnpm-home')
await mkdir(pnpmHome, { recursive: true })
addPath(bootstrapBinDir)
// PNPM_HOME/bin is where `pnpm self-update` places the target version
// binary. It must have higher PATH precedence than pnpmHome (which
// contains the bootstrap binary) so the self-updated version is found
// first. The bootstrap pnpm is invoked via absolute path, not PATH,
// so this ordering does not affect the bootstrap step.
addPath(pnpmHome)
addPath(path.join(pnpmHome, 'bin'))
exportVariable('PNPM_HOME', pnpmHome)
@@ -104,17 +107,25 @@ export async function runSelfInstaller(inputs: Inputs): Promise<SelfInstallerRes
const bootstrapVersion = native ? bootstrapNativeVersion : standalone ? bootstrapExeVersion : bootstrapPnpmVersion
if (targetVersion === bootstrapVersion || (native && satisfies(bootstrapVersion, targetVersion))) {
return { exitCode: 0, binDest: bootstrapBinDir }
return { exitCode: 0, binDest: pnpmHome }
}
const cmd = native || standalone ? bootstrapPnpm : process.execPath
const args = native || standalone ? ['self-update', targetVersion] : [bootstrapPnpm, 'self-update', targetVersion]
const exitCode = await runCommand(cmd, args, { cwd: dest })
if (exitCode !== 0) {
return { exitCode, binDest: bootstrapBinDir }
return { exitCode, binDest: pnpmHome }
}
// self-update writes the target pnpm/pnpx into PNPM_HOME/bin, leaving
// the bootstrap symlinks in pnpmHome pointing at the old version. Use
// PNPM_HOME/bin so consumers of the bin_dest output (e.g.
// `${steps.pnpm.outputs.bin_dest}/pnpm`) invoke the requested version.
//
// When the requested version resolves to the bootstrap version, self-update
// is a no-op and PNPM_HOME/bin is not created — fall back to pnpmHome,
// whose symlinks already point at the right version.
const updatedBinDir = path.join(pnpmHome, 'bin')
return { exitCode: 0, binDest: existsSync(updatedBinDir) ? updatedBinDir : bootstrapBinDir }
return { exitCode: 0, binDest: existsSync(updatedBinDir) ? updatedBinDir : pnpmHome }
}
function readTargetVersion(opts: {
@@ -211,15 +222,10 @@ function getSystemNodeVersion(): Promise<{ major: number; minor: number }> {
}
function runCommand(cmd: string, args: string[], opts: { cwd: string; env?: Record<string, string | undefined> }): Promise<number> {
return new Promise<number>((resolve, reject) => {
const cp = spawn(cmd, args, {
return exec(`"${cmd}"`, args, {
cwd: opts.cwd,
env: opts.env,
stdio: ['pipe', 'inherit', 'inherit'],
shell: process.platform === 'win32',
})
cp.on('error', reject)
cp.on('close', resolve)
env: opts.env && Object.fromEntries(Object.entries(opts.env).filter((entry): entry is [string, string] => entry[1] !== undefined)),
ignoreReturnCode: true,
})
}