4
0
Fork 0
mirror of https://github.com/actions/setup-python.git synced 2025-11-07 05:26:56 +00:00

Compare commits

...

3 commits

Author SHA1 Message Date
dependabot[bot]
631a100373
Merge d1ebd313e3 into cfd55ca824 2025-10-28 02:51:09 -05:00
Tim Felgentreff
cfd55ca824
graalpy: add graalpy early-access and windows builds (#880) 2025-10-22 11:16:57 -05:00
dependabot[bot]
d1ebd313e3
Bump eslint-plugin-jest from 27.9.0 to 29.0.1
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 27.9.0 to 29.0.1.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v27.9.0...v29.0.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-version: 29.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-23 04:06:36 +00:00
10 changed files with 1104 additions and 938 deletions

View file

@ -106,7 +106,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, macos-13] os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
- name: Setup GraalPy and check latest - name: Setup GraalPy and check latest

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@ import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as finder from '../src/find-graalpy'; import * as finder from '../src/find-graalpy';
import {IGraalPyManifestRelease, IS_WINDOWS} from '../src/utils'; import {IGraalPyManifestRelease} from '../src/utils';
import manifestData from './data/graalpy.json'; import manifestData from './data/graalpy.json';
@ -19,9 +19,6 @@ const architecture = 'x64';
const toolDir = path.join(__dirname, 'runner', 'tools'); const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp'); const tempDir = path.join(__dirname, 'runner', 'temp');
/* GraalPy doesn't have a windows release yet */
const describeSkipOnWindows = IS_WINDOWS ? describe.skip : describe;
describe('parseGraalPyVersion', () => { describe('parseGraalPyVersion', () => {
it.each([ it.each([
['graalpy-23', '23'], ['graalpy-23', '23'],
@ -108,7 +105,7 @@ describe('findGraalPyToolCache', () => {
}); });
}); });
describeSkipOnWindows('findGraalPyVersion', () => { describe('findGraalPyVersion', () => {
let getBooleanInputSpy: jest.SpyInstance; let getBooleanInputSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance; let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance; let debugSpy: jest.SpyInstance;
@ -358,13 +355,13 @@ describeSkipOnWindows('findGraalPyVersion', () => {
it('found and install successfully, pre-release fallback', async () => { it('found and install successfully, pre-release fallback', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir'); spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.1', architecture) path.join(toolDir, 'GraalPy', '24.1', architecture)
); );
spyChmodSync = jest.spyOn(fs, 'chmodSync'); spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
finder.findGraalPyVersion( finder.findGraalPyVersion(
'graalpy23.1', 'graalpy24.1',
architecture, architecture,
false, false,
false, false,
@ -372,7 +369,7 @@ describeSkipOnWindows('findGraalPyVersion', () => {
) )
).rejects.toThrow(); ).rejects.toThrow();
await expect( await expect(
finder.findGraalPyVersion('graalpy23.1', architecture, false, false, true) finder.findGraalPyVersion('graalpy24.1', architecture, false, false, true)
).resolves.toEqual('23.1.0-a.1'); ).resolves.toEqual('24.1.0-ea.9');
}); });
}); });

View file

@ -21,24 +21,21 @@ const architecture = 'x64';
const toolDir = path.join(__dirname, 'runner', 'tools'); const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp'); const tempDir = path.join(__dirname, 'runner', 'temp');
/* GraalPy doesn't have a windows release yet */
const describeSkipOnWindows = IS_WINDOWS ? describe.skip : describe;
describe('graalpyVersionToSemantic', () => { describe('graalpyVersionToSemantic', () => {
it.each([ it.each([
['23.0.0a1', '23.0.0a1'], ['graalpy-24.1.0-ea.09', '24.1.0-ea.9'],
['23.0.0', '23.0.0'], ['graal-23.0.0', '23.0.0'],
['23.0.x', '23.0.x'], ['vm-23.0.x', '23.0.x'],
['23.x', '23.x'] ['graal-23.x', '23.x']
])('%s -> %s', (input, expected) => { ])('%s -> %s', (input, expected) => {
expect(installer.graalPyTagToVersion(input)).toEqual(expected); expect(installer.graalPyTagToVersion(input)).toEqual(expected);
}); });
}); });
describeSkipOnWindows('findRelease', () => { describe('findRelease', () => {
const result = JSON.stringify(manifestData); const result = JSON.stringify(manifestData);
const releases = JSON.parse(result) as IGraalPyManifestRelease[]; const releases = JSON.parse(result) as IGraalPyManifestRelease[];
const extension = 'tar.gz'; const extension = IS_WINDOWS ? 'zip' : 'tar.gz';
const arch = installer.toGraalPyArchitecture(architecture); const arch = installer.toGraalPyArchitecture(architecture);
const platform = installer.toGraalPyPlatform(process.platform); const platform = installer.toGraalPyPlatform(process.platform);
const extensionName = `${platform}-${arch}.${extension}`; const extensionName = `${platform}-${arch}.${extension}`;
@ -47,8 +44,8 @@ describeSkipOnWindows('findRelease', () => {
browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.0.0/graalpython-23.0.0-${extensionName}` browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.0.0/graalpython-23.0.0-${extensionName}`
}; };
const filesRC1: IGraalPyManifestAsset = { const filesRC1: IGraalPyManifestAsset = {
name: `graalpython-23.1.0a1-${extensionName}`, name: `graalpy-24.1.0-ea.09-${extensionName}`,
browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.1.0a1/graalpython-23.1.0a1-${extensionName}` browser_download_url: `https://github.com/graalvm/graal-languages-ea-builds/releases/download/graalpy-24.1.0-ea.09/graalpy-24.1.0-ea.09-${extensionName}`
}; };
let warningSpy: jest.SpyInstance; let warningSpy: jest.SpyInstance;
@ -84,15 +81,15 @@ describeSkipOnWindows('findRelease', () => {
}); });
it('Preview version of GraalPy is found', () => { it('Preview version of GraalPy is found', () => {
const graalpyVersion = installer.graalPyTagToVersion('vm-23.1.0a1'); const graalpyVersion = installer.graalPyTagToVersion('vm-24.1.0-ea.09');
expect( expect(
installer.findRelease(releases, graalpyVersion, architecture, false) installer.findRelease(releases, graalpyVersion, architecture, false)
).toMatchObject({ ).toMatchObject({
foundAsset: { foundAsset: {
name: `graalpython-23.1.0a1-${extensionName}`, name: `graalpy-24.1.0-ea.09-${extensionName}`,
browser_download_url: `https://github.com/oracle/graalpython/releases/download/graal-23.1.0a1/graalpython-23.1.0a1-${extensionName}` browser_download_url: `https://github.com/graalvm/graal-languages-ea-builds/releases/download/graalpy-24.1.0-ea.09/graalpy-24.1.0-ea.09-${extensionName}`
}, },
resolvedGraalPyVersion: '23.1.0-a.1' resolvedGraalPyVersion: '24.1.0-ea.9'
}); });
}); });
@ -107,7 +104,7 @@ describeSkipOnWindows('findRelease', () => {
}); });
it('GraalPy version matches semver (pre-release)', () => { it('GraalPy version matches semver (pre-release)', () => {
const graalpyVersion = '23.1.x'; const graalpyVersion = '24.1.x';
expect( expect(
installer.findRelease(releases, graalpyVersion, architecture, false) installer.findRelease(releases, graalpyVersion, architecture, false)
).toBeNull(); ).toBeNull();
@ -115,12 +112,12 @@ describeSkipOnWindows('findRelease', () => {
installer.findRelease(releases, graalpyVersion, architecture, true) installer.findRelease(releases, graalpyVersion, architecture, true)
).toMatchObject({ ).toMatchObject({
foundAsset: filesRC1, foundAsset: filesRC1,
resolvedGraalPyVersion: '23.1.0-a.1' resolvedGraalPyVersion: '24.1.0-ea.9'
}); });
}); });
}); });
describeSkipOnWindows('installGraalPy', () => { describe('installGraalPy', () => {
let tcFind: jest.SpyInstance; let tcFind: jest.SpyInstance;
let warningSpy: jest.SpyInstance; let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance; let debugSpy: jest.SpyInstance;
@ -232,20 +229,20 @@ describeSkipOnWindows('installGraalPy', () => {
it('found and install GraalPy, pre-release fallback', async () => { it('found and install GraalPy, pre-release fallback', async () => {
spyCacheDir = jest.spyOn(tc, 'cacheDir'); spyCacheDir = jest.spyOn(tc, 'cacheDir');
spyCacheDir.mockImplementation(() => spyCacheDir.mockImplementation(() =>
path.join(toolDir, 'GraalPy', '23.1.0', architecture) path.join(toolDir, 'GraalPy', '24.1.0', architecture)
); );
spyChmodSync = jest.spyOn(fs, 'chmodSync'); spyChmodSync = jest.spyOn(fs, 'chmodSync');
spyChmodSync.mockImplementation(() => undefined); spyChmodSync.mockImplementation(() => undefined);
await expect( await expect(
installer.installGraalPy('23.1.x', architecture, false, undefined) installer.installGraalPy('24.1.x', architecture, false, undefined)
).rejects.toThrow(); ).rejects.toThrow();
await expect( await expect(
installer.installGraalPy('23.1.x', architecture, true, undefined) installer.installGraalPy('24.1.x', architecture, true, undefined)
).resolves.toEqual({ ).resolves.toEqual({
installDir: path.join(toolDir, 'GraalPy', '23.1.0', architecture), installDir: path.join(toolDir, 'GraalPy', '24.1.0', architecture),
resolvedGraalPyVersion: '23.1.0-a.1' resolvedGraalPyVersion: '24.1.0-ea.9'
}); });
expect(spyHttpClient).toHaveBeenCalled(); expect(spyHttpClient).toHaveBeenCalled();

36
dist/setup/index.js vendored
View file

@ -96769,8 +96769,8 @@ async function findGraalPyVersion(versionSpec, architecture, updateEnvironment,
const pipDir = utils_1.IS_WINDOWS ? 'Scripts' : 'bin'; const pipDir = utils_1.IS_WINDOWS ? 'Scripts' : 'bin';
const _binDir = path.join(installDir, pipDir); const _binDir = path.join(installDir, pipDir);
const binaryExtension = utils_1.IS_WINDOWS ? '.exe' : ''; const binaryExtension = utils_1.IS_WINDOWS ? '.exe' : '';
const pythonPath = path.join(utils_1.IS_WINDOWS ? installDir : _binDir, `python${binaryExtension}`); const pythonPath = path.join(_binDir, `python${binaryExtension}`);
const pythonLocation = (0, utils_1.getBinaryDirectory)(installDir); const pythonLocation = path.join(installDir, 'bin');
if (updateEnvironment) { if (updateEnvironment) {
core.exportVariable('pythonLocation', installDir); core.exportVariable('pythonLocation', installDir);
// https://cmake.org/cmake/help/latest/module/FindPython.html#module:FindPython // https://cmake.org/cmake/help/latest/module/FindPython.html#module:FindPython
@ -97315,7 +97315,12 @@ async function installGraalPy(graalpyVersion, architecture, allowPreReleases, re
try { try {
const graalpyPath = await tc.downloadTool(downloadUrl, undefined, AUTH); const graalpyPath = await tc.downloadTool(downloadUrl, undefined, AUTH);
core.info('Extracting downloaded archive...'); core.info('Extracting downloaded archive...');
downloadDir = await tc.extractTar(graalpyPath); if (utils_1.IS_WINDOWS) {
downloadDir = await tc.extractZip(graalpyPath);
}
else {
downloadDir = await tc.extractTar(graalpyPath);
}
// root folder in archive can have unpredictable name so just take the first folder // root folder in archive can have unpredictable name so just take the first folder
// downloadDir is unique folder under TEMP and can't contain any other folders // downloadDir is unique folder under TEMP and can't contain any other folders
const archiveName = fs_1.default.readdirSync(downloadDir)[0]; const archiveName = fs_1.default.readdirSync(downloadDir)[0];
@ -97324,7 +97329,7 @@ async function installGraalPy(graalpyVersion, architecture, allowPreReleases, re
if (!(0, utils_1.isNightlyKeyword)(resolvedGraalPyVersion)) { if (!(0, utils_1.isNightlyKeyword)(resolvedGraalPyVersion)) {
installDir = await tc.cacheDir(toolDir, 'GraalPy', resolvedGraalPyVersion, architecture); installDir = await tc.cacheDir(toolDir, 'GraalPy', resolvedGraalPyVersion, architecture);
} }
const binaryPath = (0, utils_1.getBinaryDirectory)(installDir); const binaryPath = path.join(installDir, 'bin');
await createGraalPySymlink(binaryPath, resolvedGraalPyVersion); await createGraalPySymlink(binaryPath, resolvedGraalPyVersion);
await installPip(binaryPath); await installPip(binaryPath);
return { installDir, resolvedGraalPyVersion }; return { installDir, resolvedGraalPyVersion };
@ -97352,6 +97357,9 @@ async function getAvailableGraalPyVersions() {
if (AUTH) { if (AUTH) {
headers.authorization = AUTH; headers.authorization = AUTH;
} }
/*
Get releases first.
*/
let url = 'https://api.github.com/repos/oracle/graalpython/releases'; let url = 'https://api.github.com/repos/oracle/graalpython/releases';
const result = []; const result = [];
do { do {
@ -97362,6 +97370,19 @@ async function getAvailableGraalPyVersions() {
result.push(...response.result); result.push(...response.result);
url = (0, utils_1.getNextPageUrl)(response); url = (0, utils_1.getNextPageUrl)(response);
} while (url); } while (url);
/*
Add pre-release builds.
*/
url =
'https://api.github.com/repos/graalvm/graal-languages-ea-builds/releases';
do {
const response = await http.getJson(url, headers);
if (!response.result) {
throw new Error(`Unable to retrieve the list of available GraalPy versions from '${url}'`);
}
result.push(...response.result);
url = (0, utils_1.getNextPageUrl)(response);
} while (url);
return result; return result;
} }
async function createGraalPySymlink(graalpyBinaryPath, graalpyVersion) { async function createGraalPySymlink(graalpyBinaryPath, graalpyVersion) {
@ -97381,7 +97402,7 @@ async function installPip(pythonLocation) {
await exec.exec(`${pythonBinary} -m ensurepip --default-pip`); await exec.exec(`${pythonBinary} -m ensurepip --default-pip`);
} }
function graalPyTagToVersion(tag) { function graalPyTagToVersion(tag) {
const versionPattern = /.*-(\d+\.\d+\.\d+(?:\.\d+)?)((?:a|b|rc))?(\d*)?/; const versionPattern = /.*-(\d+\.\d+\.\d+(?:\.\d+)?)(?:-((?:ea|a|b|rc))\.0*(\d+))?/;
const match = tag.match(versionPattern); const match = tag.match(versionPattern);
if (match && match[2]) { if (match && match[2]) {
return `${match[1]}-${match[2]}.${match[3]}`; return `${match[1]}-${match[2]}.${match[3]}`;
@ -97431,8 +97452,9 @@ function toGraalPyArchitecture(architecture) {
function findAsset(item, architecture, platform) { function findAsset(item, architecture, platform) {
const graalpyArch = toGraalPyArchitecture(architecture); const graalpyArch = toGraalPyArchitecture(architecture);
const graalpyPlatform = toGraalPyPlatform(platform); const graalpyPlatform = toGraalPyPlatform(platform);
const graalpyExt = platform == 'win32' ? 'zip' : 'tar.gz';
const found = item.assets.filter(file => file.name.startsWith('graalpy') && const found = item.assets.filter(file => file.name.startsWith('graalpy') &&
file.name.endsWith(`-${graalpyPlatform}-${graalpyArch}.tar.gz`)); file.name.endsWith(`-${graalpyPlatform}-${graalpyArch}.${graalpyExt}`));
/* /*
In the future there could be more variants of GraalPy for a single release. Pick the shortest name, that one is the most likely to be the primary variant. In the future there could be more variants of GraalPy for a single release. Pick the shortest name, that one is the most likely to be the primary variant.
*/ */
@ -98363,7 +98385,7 @@ function getVersionInputFromFile(versionFile) {
} }
} }
/** /**
* Get the directory containing interpreter binary from installation directory of PyPy or GraalPy * Get the directory containing interpreter binary from installation directory of PyPy
* - On Linux and macOS, the Python interpreter is in 'bin'. * - On Linux and macOS, the Python interpreter is in 'bin'.
* - On Windows, it is in the installation root. * - On Windows, it is in the installation root.
*/ */

237
package-lock.json generated
View file

@ -28,7 +28,7 @@
"@vercel/ncc": "^0.38.3", "@vercel/ncc": "^0.38.3",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^8.6.0", "eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.9.0", "eslint-plugin-jest": "^29.0.1",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-circus": "^29.7.0", "jest-circus": "^29.7.0",
@ -833,16 +833,20 @@
"dev": true "dev": true
}, },
"node_modules/@eslint-community/eslint-utils": { "node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.4.3"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}, },
"funding": {
"url": "https://opencollective.com/eslint"
},
"peerDependencies": { "peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
} }
@ -1726,6 +1730,42 @@
} }
} }
}, },
"node_modules/@typescript-eslint/project-service": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.1.tgz",
"integrity": "sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.34.1",
"@typescript-eslint/types": "^8.34.1",
"debug": "^4.3.4"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.1.tgz",
"integrity": "sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.62.0", "version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
@ -1743,6 +1783,23 @@
"url": "https://opencollective.com/typescript-eslint" "url": "https://opencollective.com/typescript-eslint"
} }
}, },
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.1.tgz",
"integrity": "sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "5.62.0", "version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
@ -2724,19 +2781,20 @@
} }
}, },
"node_modules/eslint-plugin-jest": { "node_modules/eslint-plugin-jest": {
"version": "27.9.0", "version": "29.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.0.1.tgz",
"integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==", "integrity": "sha512-EE44T0OSMCeXhDrrdsbKAhprobKkPtJTbQz5yEktysNpHeDZTAL1SfDTNKmcFfJkY6yrQLtTKZALrD3j/Gpmiw==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/utils": "^5.10.0" "@typescript-eslint/utils": "^8.0.0"
}, },
"engines": { "engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0" "node": "^20.12.0 || ^22.0.0 || >=24.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0", "@typescript-eslint/eslint-plugin": "^8.0.0",
"eslint": "^7.0.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0",
"jest": "*" "jest": "*"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
@ -2748,6 +2806,148 @@
} }
} }
}, },
"node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/scope-manager": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.1.tgz",
"integrity": "sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.34.1",
"@typescript-eslint/visitor-keys": "8.34.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/types": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.1.tgz",
"integrity": "sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.1.tgz",
"integrity": "sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.34.1",
"@typescript-eslint/tsconfig-utils": "8.34.1",
"@typescript-eslint/types": "8.34.1",
"@typescript-eslint/visitor-keys": "8.34.1",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^2.1.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.1.tgz",
"integrity": "sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.34.1",
"@typescript-eslint/types": "8.34.1",
"@typescript-eslint/typescript-estree": "8.34.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/visitor-keys": {
"version": "8.34.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.1.tgz",
"integrity": "sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.34.1",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-jest/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/eslint-plugin-jest/node_modules/eslint-visitor-keys": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-plugin-jest/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/eslint-plugin-node": { "node_modules/eslint-plugin-node": {
"version": "11.1.0", "version": "11.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
@ -5315,6 +5515,19 @@
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
}, },
"node_modules/ts-api-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18.12"
},
"peerDependencies": {
"typescript": ">=4.8.4"
}
},
"node_modules/ts-jest": { "node_modules/ts-jest": {
"version": "29.3.2", "version": "29.3.2",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.2.tgz", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.2.tgz",

View file

@ -47,7 +47,7 @@
"@vercel/ncc": "^0.38.3", "@vercel/ncc": "^0.38.3",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^8.6.0", "eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.9.0", "eslint-plugin-jest": "^29.0.1",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-circus": "^29.7.0", "jest-circus": "^29.7.0",

View file

@ -1,11 +1,6 @@
import * as path from 'path'; import * as path from 'path';
import * as graalpyInstall from './install-graalpy'; import * as graalpyInstall from './install-graalpy';
import { import {IS_WINDOWS, validateVersion, IGraalPyManifestRelease} from './utils';
IS_WINDOWS,
validateVersion,
IGraalPyManifestRelease,
getBinaryDirectory
} from './utils';
import * as semver from 'semver'; import * as semver from 'semver';
import * as core from '@actions/core'; import * as core from '@actions/core';
@ -62,11 +57,8 @@ export async function findGraalPyVersion(
const pipDir = IS_WINDOWS ? 'Scripts' : 'bin'; const pipDir = IS_WINDOWS ? 'Scripts' : 'bin';
const _binDir = path.join(installDir, pipDir); const _binDir = path.join(installDir, pipDir);
const binaryExtension = IS_WINDOWS ? '.exe' : ''; const binaryExtension = IS_WINDOWS ? '.exe' : '';
const pythonPath = path.join( const pythonPath = path.join(_binDir, `python${binaryExtension}`);
IS_WINDOWS ? installDir : _binDir, const pythonLocation = path.join(installDir, 'bin');
`python${binaryExtension}`
);
const pythonLocation = getBinaryDirectory(installDir);
if (updateEnvironment) { if (updateEnvironment) {
core.exportVariable('pythonLocation', installDir); core.exportVariable('pythonLocation', installDir);
// https://cmake.org/cmake/help/latest/module/FindPython.html#module:FindPython // https://cmake.org/cmake/help/latest/module/FindPython.html#module:FindPython

View file

@ -15,7 +15,6 @@ import {
IGraalPyManifestRelease, IGraalPyManifestRelease,
createSymlinkInFolder, createSymlinkInFolder,
isNightlyKeyword, isNightlyKeyword,
getBinaryDirectory,
getNextPageUrl getNextPageUrl
} from './utils'; } from './utils';
@ -64,7 +63,11 @@ export async function installGraalPy(
const graalpyPath = await tc.downloadTool(downloadUrl, undefined, AUTH); const graalpyPath = await tc.downloadTool(downloadUrl, undefined, AUTH);
core.info('Extracting downloaded archive...'); core.info('Extracting downloaded archive...');
downloadDir = await tc.extractTar(graalpyPath); if (IS_WINDOWS) {
downloadDir = await tc.extractZip(graalpyPath);
} else {
downloadDir = await tc.extractTar(graalpyPath);
}
// root folder in archive can have unpredictable name so just take the first folder // root folder in archive can have unpredictable name so just take the first folder
// downloadDir is unique folder under TEMP and can't contain any other folders // downloadDir is unique folder under TEMP and can't contain any other folders
@ -81,7 +84,7 @@ export async function installGraalPy(
); );
} }
const binaryPath = getBinaryDirectory(installDir); const binaryPath = path.join(installDir, 'bin');
await createGraalPySymlink(binaryPath, resolvedGraalPyVersion); await createGraalPySymlink(binaryPath, resolvedGraalPyVersion);
await installPip(binaryPath); await installPip(binaryPath);
@ -115,6 +118,9 @@ export async function getAvailableGraalPyVersions() {
headers.authorization = AUTH; headers.authorization = AUTH;
} }
/*
Get releases first.
*/
let url: string | null = let url: string | null =
'https://api.github.com/repos/oracle/graalpython/releases'; 'https://api.github.com/repos/oracle/graalpython/releases';
const result: IGraalPyManifestRelease[] = []; const result: IGraalPyManifestRelease[] = [];
@ -130,6 +136,23 @@ export async function getAvailableGraalPyVersions() {
url = getNextPageUrl(response); url = getNextPageUrl(response);
} while (url); } while (url);
/*
Add pre-release builds.
*/
url =
'https://api.github.com/repos/graalvm/graal-languages-ea-builds/releases';
do {
const response: ifm.TypedResponse<IGraalPyManifestRelease[]> =
await http.getJson(url, headers);
if (!response.result) {
throw new Error(
`Unable to retrieve the list of available GraalPy versions from '${url}'`
);
}
result.push(...response.result);
url = getNextPageUrl(response);
} while (url);
return result; return result;
} }
@ -175,7 +198,8 @@ async function installPip(pythonLocation: string) {
} }
export function graalPyTagToVersion(tag: string) { export function graalPyTagToVersion(tag: string) {
const versionPattern = /.*-(\d+\.\d+\.\d+(?:\.\d+)?)((?:a|b|rc))?(\d*)?/; const versionPattern =
/.*-(\d+\.\d+\.\d+(?:\.\d+)?)(?:-((?:ea|a|b|rc))\.0*(\d+))?/;
const match = tag.match(versionPattern); const match = tag.match(versionPattern);
if (match && match[2]) { if (match && match[2]) {
return `${match[1]}-${match[2]}.${match[3]}`; return `${match[1]}-${match[2]}.${match[3]}`;
@ -251,10 +275,11 @@ export function findAsset(
) { ) {
const graalpyArch = toGraalPyArchitecture(architecture); const graalpyArch = toGraalPyArchitecture(architecture);
const graalpyPlatform = toGraalPyPlatform(platform); const graalpyPlatform = toGraalPyPlatform(platform);
const graalpyExt = platform == 'win32' ? 'zip' : 'tar.gz';
const found = item.assets.filter( const found = item.assets.filter(
file => file =>
file.name.startsWith('graalpy') && file.name.startsWith('graalpy') &&
file.name.endsWith(`-${graalpyPlatform}-${graalpyArch}.tar.gz`) file.name.endsWith(`-${graalpyPlatform}-${graalpyArch}.${graalpyExt}`)
); );
/* /*
In the future there could be more variants of GraalPy for a single release. Pick the shortest name, that one is the most likely to be the primary variant. In the future there could be more variants of GraalPy for a single release. Pick the shortest name, that one is the most likely to be the primary variant.

View file

@ -379,7 +379,7 @@ export function getVersionInputFromFile(versionFile: string): string[] {
} }
/** /**
* Get the directory containing interpreter binary from installation directory of PyPy or GraalPy * Get the directory containing interpreter binary from installation directory of PyPy
* - On Linux and macOS, the Python interpreter is in 'bin'. * - On Linux and macOS, the Python interpreter is in 'bin'.
* - On Windows, it is in the installation root. * - On Windows, it is in the installation root.
*/ */