mirror of
https://github.com/actions/setup-java.git
synced 2026-07-08 14:21:50 +00:00
fix: convert Windows paths to POSIX format for MSYS2 GPG on Windows
The Git-bundled GPG on Windows (C:\Program Files\Git\usr\bin\gpg.exe) is an MSYS2-based binary that uses POSIX path conventions internally. When Windows-style paths with backslashes and drive letters (D:\a\_temp\...) are passed as arguments, GPG may fail to resolve them correctly, resulting in a fatal error (exit code 2). Fix: add a toGpgPath() helper that converts Windows paths to MSYS2 POSIX format (/d/a/_temp/...) before passing them to any gpg command. On Linux and macOS the helper is a no-op. Applied to all four paths used in verifyPackageSignature: - gpgHome (--homedir argument) - publicKeyFile (--import argument) - signaturePath (--verify signature argument) - archivePath (--verify data argument)
This commit is contained in:
parent
801240703e
commit
2c98690265
@ -32,6 +32,35 @@ describe('gpg tests', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('toGpgPath', () => {
|
||||||
|
const originalPlatform = process.platform;
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
Object.defineProperty(process, 'platform', {value: originalPlatform});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns path unchanged on non-Windows platforms', () => {
|
||||||
|
Object.defineProperty(process, 'platform', {value: 'linux'});
|
||||||
|
expect(gpg.toGpgPath('/tmp/some/path')).toBe('/tmp/some/path');
|
||||||
|
expect(gpg.toGpgPath('D:\\a\\_temp\\file')).toBe('D:\\a\\_temp\\file');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts Windows backslashes and drive letter to POSIX path on Windows', () => {
|
||||||
|
Object.defineProperty(process, 'platform', {value: 'win32'});
|
||||||
|
expect(gpg.toGpgPath('D:\\a\\_temp\\gpg-home')).toBe(
|
||||||
|
'/d/a/_temp/gpg-home'
|
||||||
|
);
|
||||||
|
expect(gpg.toGpgPath('C:\\Users\\runner\\AppData\\Local\\Temp\\key.asc')).toBe(
|
||||||
|
'/c/Users/runner/AppData/Local/Temp/key.asc'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles uppercase and lowercase drive letters on Windows', () => {
|
||||||
|
Object.defineProperty(process, 'platform', {value: 'win32'});
|
||||||
|
expect(gpg.toGpgPath('d:\\a\\_temp\\file')).toBe('/d/a/_temp/file');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('importKey', () => {
|
describe('importKey', () => {
|
||||||
it('attempts to import private key and returns null key id on failure', async () => {
|
it('attempts to import private key and returns null key id on failure', async () => {
|
||||||
const privateKey = 'KEY CONTENTS';
|
const privateKey = 'KEY CONTENTS';
|
||||||
|
|||||||
31
dist/cleanup/index.js
vendored
31
dist/cleanup/index.js
vendored
@ -52313,7 +52313,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.verifyPackageSignature = exports.deleteKey = exports.importKey = exports.PRIVATE_KEY_FILE = void 0;
|
exports.verifyPackageSignature = exports.deleteKey = exports.importKey = exports.toGpgPath = exports.PRIVATE_KEY_FILE = void 0;
|
||||||
const fs = __importStar(__nccwpck_require__(79896));
|
const fs = __importStar(__nccwpck_require__(79896));
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
const path = __importStar(__nccwpck_require__(16928));
|
||||||
const io = __importStar(__nccwpck_require__(94994));
|
const io = __importStar(__nccwpck_require__(94994));
|
||||||
@ -52322,6 +52322,18 @@ const tc = __importStar(__nccwpck_require__(33472));
|
|||||||
const util = __importStar(__nccwpck_require__(54527));
|
const util = __importStar(__nccwpck_require__(54527));
|
||||||
exports.PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
|
exports.PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
|
||||||
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
|
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
|
||||||
|
// Convert a Windows path (D:\a\_temp\...) to a POSIX path (/d/a/_temp/...).
|
||||||
|
// The Git-bundled GPG on Windows (MSYS2-based) uses POSIX path conventions
|
||||||
|
// internally. Passing Windows paths with backslashes can cause fatal GPG errors
|
||||||
|
// (exit code 2), so all paths passed to GPG must be in POSIX format on Windows.
|
||||||
|
function toGpgPath(p) {
|
||||||
|
if (process.platform !== 'win32')
|
||||||
|
return p;
|
||||||
|
return p
|
||||||
|
.replace(/\\/g, '/')
|
||||||
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
|
}
|
||||||
|
exports.toGpgPath = toGpgPath;
|
||||||
function importKey(privateKey) {
|
function importKey(privateKey) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
fs.writeFileSync(exports.PRIVATE_KEY_FILE, privateKey, {
|
fs.writeFileSync(exports.PRIVATE_KEY_FILE, privateKey, {
|
||||||
@ -52378,8 +52390,21 @@ function verifyPackageSignature(archivePath, signatureUrl, publicKeyContent) {
|
|||||||
const publicKeyFile = path.join(gpgHome, 'public-key.asc');
|
const publicKeyFile = path.join(gpgHome, 'public-key.asc');
|
||||||
fs.writeFileSync(publicKeyFile, publicKeyContent, { encoding: 'utf-8' });
|
fs.writeFileSync(publicKeyFile, publicKeyContent, { encoding: 'utf-8' });
|
||||||
const options = { silent: true };
|
const options = { silent: true };
|
||||||
yield exec.exec('gpg', ['--homedir', gpgHome, '--batch', '--import', publicKeyFile], options);
|
yield exec.exec('gpg', [
|
||||||
yield exec.exec('gpg', ['--homedir', gpgHome, '--batch', '--verify', signaturePath, archivePath], options);
|
'--homedir',
|
||||||
|
toGpgPath(gpgHome),
|
||||||
|
'--batch',
|
||||||
|
'--import',
|
||||||
|
toGpgPath(publicKeyFile)
|
||||||
|
], options);
|
||||||
|
yield exec.exec('gpg', [
|
||||||
|
'--homedir',
|
||||||
|
toGpgPath(gpgHome),
|
||||||
|
'--batch',
|
||||||
|
'--verify',
|
||||||
|
toGpgPath(signaturePath),
|
||||||
|
toGpgPath(archivePath)
|
||||||
|
], options);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
yield io.rmRF(signaturePath);
|
yield io.rmRF(signaturePath);
|
||||||
|
|||||||
31
dist/setup/index.js
vendored
31
dist/setup/index.js
vendored
@ -81093,7 +81093,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.verifyPackageSignature = exports.deleteKey = exports.importKey = exports.PRIVATE_KEY_FILE = void 0;
|
exports.verifyPackageSignature = exports.deleteKey = exports.importKey = exports.toGpgPath = exports.PRIVATE_KEY_FILE = void 0;
|
||||||
const fs = __importStar(__nccwpck_require__(79896));
|
const fs = __importStar(__nccwpck_require__(79896));
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
const path = __importStar(__nccwpck_require__(16928));
|
||||||
const io = __importStar(__nccwpck_require__(94994));
|
const io = __importStar(__nccwpck_require__(94994));
|
||||||
@ -81102,6 +81102,18 @@ const tc = __importStar(__nccwpck_require__(33472));
|
|||||||
const util = __importStar(__nccwpck_require__(54527));
|
const util = __importStar(__nccwpck_require__(54527));
|
||||||
exports.PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
|
exports.PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
|
||||||
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
|
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
|
||||||
|
// Convert a Windows path (D:\a\_temp\...) to a POSIX path (/d/a/_temp/...).
|
||||||
|
// The Git-bundled GPG on Windows (MSYS2-based) uses POSIX path conventions
|
||||||
|
// internally. Passing Windows paths with backslashes can cause fatal GPG errors
|
||||||
|
// (exit code 2), so all paths passed to GPG must be in POSIX format on Windows.
|
||||||
|
function toGpgPath(p) {
|
||||||
|
if (process.platform !== 'win32')
|
||||||
|
return p;
|
||||||
|
return p
|
||||||
|
.replace(/\\/g, '/')
|
||||||
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
|
}
|
||||||
|
exports.toGpgPath = toGpgPath;
|
||||||
function importKey(privateKey) {
|
function importKey(privateKey) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
fs.writeFileSync(exports.PRIVATE_KEY_FILE, privateKey, {
|
fs.writeFileSync(exports.PRIVATE_KEY_FILE, privateKey, {
|
||||||
@ -81158,8 +81170,21 @@ function verifyPackageSignature(archivePath, signatureUrl, publicKeyContent) {
|
|||||||
const publicKeyFile = path.join(gpgHome, 'public-key.asc');
|
const publicKeyFile = path.join(gpgHome, 'public-key.asc');
|
||||||
fs.writeFileSync(publicKeyFile, publicKeyContent, { encoding: 'utf-8' });
|
fs.writeFileSync(publicKeyFile, publicKeyContent, { encoding: 'utf-8' });
|
||||||
const options = { silent: true };
|
const options = { silent: true };
|
||||||
yield exec.exec('gpg', ['--homedir', gpgHome, '--batch', '--import', publicKeyFile], options);
|
yield exec.exec('gpg', [
|
||||||
yield exec.exec('gpg', ['--homedir', gpgHome, '--batch', '--verify', signaturePath, archivePath], options);
|
'--homedir',
|
||||||
|
toGpgPath(gpgHome),
|
||||||
|
'--batch',
|
||||||
|
'--import',
|
||||||
|
toGpgPath(publicKeyFile)
|
||||||
|
], options);
|
||||||
|
yield exec.exec('gpg', [
|
||||||
|
'--homedir',
|
||||||
|
toGpgPath(gpgHome),
|
||||||
|
'--batch',
|
||||||
|
'--verify',
|
||||||
|
toGpgPath(signaturePath),
|
||||||
|
toGpgPath(archivePath)
|
||||||
|
], options);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
yield io.rmRF(signaturePath);
|
yield io.rmRF(signaturePath);
|
||||||
|
|||||||
28
src/gpg.ts
28
src/gpg.ts
@ -10,6 +10,17 @@ export const PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
|
|||||||
|
|
||||||
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
|
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
|
||||||
|
|
||||||
|
// Convert a Windows path (D:\a\_temp\...) to a POSIX path (/d/a/_temp/...).
|
||||||
|
// The Git-bundled GPG on Windows (MSYS2-based) uses POSIX path conventions
|
||||||
|
// internally. Passing Windows paths with backslashes can cause fatal GPG errors
|
||||||
|
// (exit code 2), so all paths passed to GPG must be in POSIX format on Windows.
|
||||||
|
export function toGpgPath(p: string): string {
|
||||||
|
if (process.platform !== 'win32') return p;
|
||||||
|
return p
|
||||||
|
.replace(/\\/g, '/')
|
||||||
|
.replace(/^([A-Za-z]):\//, (_, drive) => `/${drive.toLowerCase()}/`);
|
||||||
|
}
|
||||||
|
|
||||||
export async function importKey(privateKey: string) {
|
export async function importKey(privateKey: string) {
|
||||||
fs.writeFileSync(PRIVATE_KEY_FILE, privateKey, {
|
fs.writeFileSync(PRIVATE_KEY_FILE, privateKey, {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
@ -84,12 +95,25 @@ export async function verifyPackageSignature(
|
|||||||
const options: ExecOptions = {silent: true};
|
const options: ExecOptions = {silent: true};
|
||||||
await exec.exec(
|
await exec.exec(
|
||||||
'gpg',
|
'gpg',
|
||||||
['--homedir', gpgHome, '--batch', '--import', publicKeyFile],
|
[
|
||||||
|
'--homedir',
|
||||||
|
toGpgPath(gpgHome),
|
||||||
|
'--batch',
|
||||||
|
'--import',
|
||||||
|
toGpgPath(publicKeyFile)
|
||||||
|
],
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
await exec.exec(
|
await exec.exec(
|
||||||
'gpg',
|
'gpg',
|
||||||
['--homedir', gpgHome, '--batch', '--verify', signaturePath, archivePath],
|
[
|
||||||
|
'--homedir',
|
||||||
|
toGpgPath(gpgHome),
|
||||||
|
'--batch',
|
||||||
|
'--verify',
|
||||||
|
toGpgPath(signaturePath),
|
||||||
|
toGpgPath(archivePath)
|
||||||
|
],
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user