Merge branch 'main' into copilot/macos-self-hosted-runners-fix

This commit is contained in:
Bruno Borges
2026-09-09 02:20:38 -04:00
committed by GitHub
10 changed files with 226 additions and 8 deletions
+87
View File
@@ -0,0 +1,87 @@
import {afterAll, beforeAll, describe, expect, it} from '@jest/globals';
import {spawnSync} from 'child_process';
import fs from 'fs';
import os from 'os';
import path from 'path';
import {fileURLToPath, pathToFileURL} from 'url';
const dist = fileURLToPath(new URL('../dist/', import.meta.url));
let tempDir: string;
let linkedDist: string;
beforeAll(() => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-java-entrypoints-'));
linkedDist = path.join(tempDir, 'linked # dist');
fs.symlinkSync(dist, linkedDist, 'junction');
});
afterAll(() => {
fs.rmSync(tempDir, {recursive: true, force: true});
});
function execute(args: string[], input?: string) {
return spawnSync(process.execPath, args, {
encoding: 'utf8',
input,
timeout: 10000,
env: {
PATH: process.env.PATH,
SystemRoot: process.env.SystemRoot
}
});
}
describe.each([
['setup', 1, 'java-version or java-version-file input expected'],
['cleanup', 0, '']
] as const)('%s entrypoint', (name, exitCode, output) => {
it.each(['direct', 'symlink', 'preserved symlink'])(
'executes through a %s path',
mode => {
const entry = path.join(
mode === 'direct' ? dist : linkedDist,
name,
'index.js'
);
const args =
mode === 'preserved symlink'
? ['--preserve-symlinks-main', entry]
: [entry];
const result = execute(args);
expect(result.error).toBeUndefined();
expect(result.status).toBe(exitCode);
expect(result.stderr).toBe('');
expect(result.stdout).not.toContain('skipping the execution');
if (output) {
expect(result.stdout).toContain(output);
} else {
expect(result.stdout).toBe('');
}
}
);
it.each(['eval', 'stdin', 'file'])(
'does not execute when imported from %s',
mode => {
const moduleUrl = pathToFileURL(path.join(dist, name, 'index.js')).href;
const source = `const {run} = await import(${JSON.stringify(moduleUrl)}); console.log(typeof run);`;
const importer = path.join(tempDir, `${name}-importer.mjs`);
fs.writeFileSync(importer, source);
const args =
mode === 'file'
? [importer]
: mode === 'eval'
? ['--input-type=module', '-e', source]
: ['--input-type=module', '-'];
const result = execute(args, mode === 'stdin' ? source : undefined);
expect(result.error).toBeUndefined();
expect(result.status).toBe(0);
expect(result.stderr).toBe('');
expect(result.stdout).toContain('skipping the execution');
expect(result.stdout).toContain('function');
expect(result.stdout).not.toContain('::error::');
}
);
});
+52
View File
@@ -0,0 +1,52 @@
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
import fs from 'fs';
import {isMainModule} from '../src/is-main-module.js';
describe('main module detection', () => {
const originalArgv = process.argv;
beforeEach(() => {
process.argv = [process.execPath, 'entrypoint.js'];
});
afterEach(() => {
process.argv = originalArgv;
jest.restoreAllMocks();
});
it.each([undefined, '-'])(
'skips filesystem access when argv[1] is %s',
entrypoint => {
process.argv =
entrypoint === undefined
? [process.execPath]
: [process.execPath, entrypoint];
const realpath = jest.spyOn(fs, 'realpathSync');
expect(isMainModule(import.meta.url)).toBe(false);
expect(realpath).not.toHaveBeenCalled();
}
);
it.each(['ENOENT', 'ENOTDIR'])(
'treats a non-file entrypoint returning %s as an import',
code => {
jest.spyOn(fs, 'realpathSync').mockImplementation(() => {
throw Object.assign(new Error('No file-based entrypoint'), {code});
});
expect(isMainModule(import.meta.url)).toBe(false);
}
);
it('propagates unexpected filesystem errors', () => {
const error = Object.assign(new Error('Permission denied'), {
code: 'EACCES'
});
jest.spyOn(fs, 'realpathSync').mockImplementation(() => {
throw error;
});
expect(() => isMainModule(import.meta.url)).toThrow(error);
});
});
@@ -27,6 +27,7 @@ jest.unstable_mockModule('@actions/core', () => ({
jest.unstable_mockModule('fs', () => ({ jest.unstable_mockModule('fs', () => ({
default: { default: {
...jest.requireActual<typeof import('fs')>('fs'),
readFileSync: jest.fn() readFileSync: jest.fn()
} }
})); }));
+1
View File
@@ -27,6 +27,7 @@ jest.unstable_mockModule('@actions/core', () => ({
jest.unstable_mockModule('fs', () => ({ jest.unstable_mockModule('fs', () => ({
default: { default: {
...jest.requireActual<typeof import('fs')>('fs'),
readFileSync: jest.fn() readFileSync: jest.fn()
} }
})); }));
+26 -1
View File
@@ -35747,6 +35747,7 @@ __nccwpck_require__.d(__webpack_exports__, {
var cleanup_java_core = __nccwpck_require__(3838); var cleanup_java_core = __nccwpck_require__(3838);
// EXTERNAL MODULE: external "fs" // EXTERNAL MODULE: external "fs"
var external_fs_ = __nccwpck_require__(9896); var external_fs_ = __nccwpck_require__(9896);
var external_fs_default = /*#__PURE__*/__nccwpck_require__.n(external_fs_);
// EXTERNAL MODULE: external "path" // EXTERNAL MODULE: external "path"
var external_path_ = __nccwpck_require__(6928); var external_path_ = __nccwpck_require__(6928);
// EXTERNAL MODULE: external "crypto" // EXTERNAL MODULE: external "crypto"
@@ -35892,6 +35893,30 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
var constants = __nccwpck_require__(7242); var constants = __nccwpck_require__(7242);
// EXTERNAL MODULE: external "url" // EXTERNAL MODULE: external "url"
var external_url_ = __nccwpck_require__(7016); var external_url_ = __nccwpck_require__(7016);
;// CONCATENATED MODULE: ./src/is-main-module.ts
function isMainModule(moduleUrl) {
const entrypoint = process.argv[1];
if (!entrypoint || entrypoint === '-') {
return false;
}
let entrypointPath;
try {
entrypointPath = external_fs_default().realpathSync(entrypoint);
}
catch (error) {
if (error instanceof Error &&
'code' in error &&
(error.code === 'ENOENT' || error.code === 'ENOTDIR')) {
return false;
}
throw error;
}
// Resolve both paths for runtimes using --preserve-symlinks-main.
return entrypointPath === external_fs_default().realpathSync((0,external_url_.fileURLToPath)(moduleUrl));
}
;// CONCATENATED MODULE: ./src/cleanup-java.ts ;// CONCATENATED MODULE: ./src/cleanup-java.ts
@@ -35959,7 +35984,7 @@ async function run() {
await cleanup_java_removeGpgHome(); await cleanup_java_removeGpgHome();
await ignoreError(saveCaches()); await ignoreError(saveCaches());
} }
if (process.argv[1] === (0,external_url_.fileURLToPath)(import.meta.url)) { if (isMainModule(import.meta.url)) {
run(); run();
} }
else { else {
+26 -1
View File
@@ -36354,6 +36354,30 @@ function configureProblemMatcher(matcherPath) {
// EXTERNAL MODULE: ./src/toolchain-ids.ts // EXTERNAL MODULE: ./src/toolchain-ids.ts
var toolchain_ids = __nccwpck_require__(7083); var toolchain_ids = __nccwpck_require__(7083);
;// CONCATENATED MODULE: ./src/is-main-module.ts
function isMainModule(moduleUrl) {
const entrypoint = process.argv[1];
if (!entrypoint || entrypoint === '-') {
return false;
}
let entrypointPath;
try {
entrypointPath = external_fs_default().realpathSync(entrypoint);
}
catch (error) {
if (error instanceof Error &&
'code' in error &&
(error.code === 'ENOENT' || error.code === 'ENOTDIR')) {
return false;
}
throw error;
}
// Resolve both paths for runtimes using --preserve-symlinks-main.
return entrypointPath === external_fs_default().realpathSync((0,external_url_.fileURLToPath)(moduleUrl));
}
;// CONCATENATED MODULE: ./src/setup-java.ts ;// CONCATENATED MODULE: ./src/setup-java.ts
@@ -36364,6 +36388,7 @@ var toolchain_ids = __nccwpck_require__(7083);
async function run() { async function run() {
const versions = setup_java_core/* getMultilineInput */.q3(constants/* INPUT_JAVA_VERSION */.QM); const versions = setup_java_core/* getMultilineInput */.q3(constants/* INPUT_JAVA_VERSION */.QM);
let distributionName = setup_java_core/* getInput */.V4(constants/* INPUT_DISTRIBUTION */.g_); let distributionName = setup_java_core/* getInput */.V4(constants/* INPUT_DISTRIBUTION */.g_);
@@ -36480,7 +36505,7 @@ async function validateCacheInput(cache) {
function settle(promise) { function settle(promise) {
return promise.then(value => ({ status: 'fulfilled', value }), reason => ({ status: 'rejected', reason })); return promise.then(value => ({ status: 'fulfilled', value }), reason => ({ status: 'rejected', reason }));
} }
if (process.argv[1] === (0,external_url_.fileURLToPath)(import.meta.url)) { if (isMainModule(import.meta.url)) {
run(); run();
} }
else { else {
+3 -3
View File
@@ -4830,9 +4830,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/js-yaml": { "node_modules/js-yaml": {
"version": "3.15.1", "version": "3.15.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz",
"integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
+2 -2
View File
@@ -6,7 +6,7 @@ import {
isJdkCacheEnabled, isJdkCacheEnabled,
isJobStatusSuccess isJobStatusSuccess
} from './util.js'; } from './util.js';
import {fileURLToPath} from 'url'; import {isMainModule} from './is-main-module.js';
async function removeGpgHome() { async function removeGpgHome() {
const gpgHome = core.getState(constants.STATE_GPG_HOME); const gpgHome = core.getState(constants.STATE_GPG_HOME);
@@ -77,7 +77,7 @@ export async function run() {
await ignoreError(saveCaches()); await ignoreError(saveCaches());
} }
if (process.argv[1] === fileURLToPath(import.meta.url)) { if (isMainModule(import.meta.url)) {
run(); run();
} else { } else {
// https://nodejs.org/api/modules.html#modules_accessing_the_main_module // https://nodejs.org/api/modules.html#modules_accessing_the_main_module
+26
View File
@@ -0,0 +1,26 @@
import fs from 'fs';
import {fileURLToPath} from 'url';
export function isMainModule(moduleUrl: string): boolean {
const entrypoint = process.argv[1];
if (!entrypoint || entrypoint === '-') {
return false;
}
let entrypointPath: string;
try {
entrypointPath = fs.realpathSync(entrypoint);
} catch (error) {
if (
error instanceof Error &&
'code' in error &&
(error.code === 'ENOENT' || error.code === 'ENOTDIR')
) {
return false;
}
throw error;
}
// Resolve both paths for runtimes using --preserve-symlinks-main.
return entrypointPath === fs.realpathSync(fileURLToPath(moduleUrl));
}
+2 -1
View File
@@ -12,6 +12,7 @@ import {getJavaDistribution} from './distributions/distribution-factory.js';
import {JavaInstallerOptions} from './distributions/base-models.js'; import {JavaInstallerOptions} from './distributions/base-models.js';
import {configureProblemMatcher} from './problem-matcher.js'; import {configureProblemMatcher} from './problem-matcher.js';
import {validateToolchainIds} from './toolchain-ids.js'; import {validateToolchainIds} from './toolchain-ids.js';
import {isMainModule} from './is-main-module.js';
export async function run() { export async function run() {
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION); const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION);
@@ -172,7 +173,7 @@ function settle<T>(promise: Promise<T>): Promise<PromiseSettledResult<T>> {
); );
} }
if (process.argv[1] === fileURLToPath(import.meta.url)) { if (isMainModule(import.meta.url)) {
run(); run();
} else { } else {
// https://nodejs.org/api/modules.html#modules_accessing_the_main_module // https://nodejs.org/api/modules.html#modules_accessing_the_main_module