Compare commits

..

3 Commits

Author SHA1 Message Date
e4cb839aaa Bump prettier from 3.5.3 to 3.6.2
Bumps [prettier](https://github.com/prettier/prettier) from 3.5.3 to 3.6.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.5.3...3.6.2)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.6.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:02:19 +00:00
cfd55ca824 graalpy: add graalpy early-access and windows builds (#880) 2025-10-22 11:16:57 -05:00
bba65e51ff Bump typescript from 5.4.2 to 5.9.3 and update docs/advanced-usage.md (#1094)
* Bump typescript from 5.4.2 to 5.8.3

Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.4.2 to 5.8.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.4.2...v5.8.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.8.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update header text from 'Linux' to 'Ubuntu'

* update target to ES2022

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: priya-kinthali <priya-kinthali@github.com>
2025-10-20 11:11:26 -05:00
14 changed files with 1958 additions and 2087 deletions

View File

@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Update the ${{ env.TAG_NAME }} tag - name: Update the ${{ env.TAG_NAME }} tag
uses: actions/publish-action@v0.4.0 uses: actions/publish-action@v0.3.0
with: with:
source-tag: ${{ env.TAG_NAME }} source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }} slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

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();

View File

@ -87714,22 +87714,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
}) : function(o, v) { }) : function(o, v) {
o["default"] = v; o["default"] = v;
}); });
var __importStar = (this && this.__importStar) || function (mod) { var __importStar = (this && this.__importStar) || (function () {
if (mod && mod.__esModule) return mod; var ownKeys = function(o) {
var result = {}; ownKeys = Object.getOwnPropertyNames || function (o) {
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); var ar = [];
__setModuleDefault(result, mod); for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return result; return ar;
}; };
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return ownKeys(o);
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } };
return new (P || (P = Promise))(function (resolve, reject) { return function (mod) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } if (mod && mod.__esModule) return mod;
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } var result = {};
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
step((generator = generator.apply(thisArg, _arguments || [])).next()); __setModuleDefault(result, mod);
}); return result;
}; };
})();
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.State = void 0; exports.State = void 0;
const cache = __importStar(__nccwpck_require__(5116)); const cache = __importStar(__nccwpck_require__(5116));
@ -87742,41 +87743,39 @@ var State;
State["CACHE_PATHS"] = "cache-paths"; State["CACHE_PATHS"] = "cache-paths";
})(State || (exports.State = State = {})); })(State || (exports.State = State = {}));
class CacheDistributor { class CacheDistributor {
packageManager;
cacheDependencyPath;
CACHE_KEY_PREFIX = 'setup-python';
constructor(packageManager, cacheDependencyPath) { constructor(packageManager, cacheDependencyPath) {
this.packageManager = packageManager; this.packageManager = packageManager;
this.cacheDependencyPath = cacheDependencyPath; this.cacheDependencyPath = cacheDependencyPath;
this.CACHE_KEY_PREFIX = 'setup-python';
} }
handleLoadedCache() { async handleLoadedCache() { }
return __awaiter(this, void 0, void 0, function* () { }); async restoreCache() {
} const { primaryKey, restoreKey } = await this.computeKeys();
restoreCache() { if (primaryKey.endsWith('-')) {
return __awaiter(this, void 0, void 0, function* () { const file = this.packageManager === 'pip'
const { primaryKey, restoreKey } = yield this.computeKeys(); ? `${this.cacheDependencyPath
if (primaryKey.endsWith('-')) { .split('\n')
const file = this.packageManager === 'pip' .join(',')} or ${constants_1.CACHE_DEPENDENCY_BACKUP_PATH}`
? `${this.cacheDependencyPath : this.cacheDependencyPath.split('\n').join(',');
.split('\n') throw new Error(`No file in ${process.cwd()} matched to [${file}], make sure you have checked out the target repository`);
.join(',')} or ${constants_1.CACHE_DEPENDENCY_BACKUP_PATH}` }
: this.cacheDependencyPath.split('\n').join(','); const cachePath = await this.getCacheGlobalDirectories();
throw new Error(`No file in ${process.cwd()} matched to [${file}], make sure you have checked out the target repository`); core.saveState(State.CACHE_PATHS, cachePath);
} let matchedKey;
const cachePath = yield this.getCacheGlobalDirectories(); try {
core.saveState(State.CACHE_PATHS, cachePath); matchedKey = await cache.restoreCache(cachePath, primaryKey, restoreKey);
let matchedKey; }
try { catch (err) {
matchedKey = yield cache.restoreCache(cachePath, primaryKey, restoreKey); const message = err.message;
} core.info(`[warning]${message}`);
catch (err) { core.setOutput('cache-hit', false);
const message = err.message; return;
core.info(`[warning]${message}`); }
core.setOutput('cache-hit', false); core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey);
return; await this.handleLoadedCache();
} this.handleMatchResult(matchedKey, primaryKey);
core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey);
yield this.handleLoadedCache();
this.handleMatchResult(matchedKey, primaryKey);
});
} }
handleMatchResult(matchedKey, primaryKey) { handleMatchResult(matchedKey, primaryKey) {
if (matchedKey) { if (matchedKey) {
@ -87827,27 +87826,28 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
}) : function(o, v) { }) : function(o, v) {
o["default"] = v; o["default"] = v;
}); });
var __importStar = (this && this.__importStar) || function (mod) { var __importStar = (this && this.__importStar) || (function () {
if (mod && mod.__esModule) return mod; var ownKeys = function(o) {
var result = {}; ownKeys = Object.getOwnPropertyNames || function (o) {
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); var ar = [];
__setModuleDefault(result, mod); for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return result; return ar;
}; };
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return ownKeys(o);
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } };
return new (P || (P = Promise))(function (resolve, reject) { return function (mod) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } if (mod && mod.__esModule) return mod;
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } var result = {};
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
step((generator = generator.apply(thisArg, _arguments || [])).next()); __setModuleDefault(result, mod);
}); return result;
}; };
})();
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.run = void 0; exports.run = run;
const core = __importStar(__nccwpck_require__(7484)); const core = __importStar(__nccwpck_require__(7484));
const cache = __importStar(__nccwpck_require__(5116)); const cache = __importStar(__nccwpck_require__(5116));
const fs_1 = __importDefault(__nccwpck_require__(9896)); const fs_1 = __importDefault(__nccwpck_require__(9896));
@ -87855,62 +87855,57 @@ const cache_distributor_1 = __nccwpck_require__(2326);
// Added early exit to resolve issue with slow post action step: // Added early exit to resolve issue with slow post action step:
// - https://github.com/actions/setup-node/issues/878 // - https://github.com/actions/setup-node/issues/878
// https://github.com/actions/cache/pull/1217 // https://github.com/actions/cache/pull/1217
function run(earlyExit) { async function run(earlyExit) {
return __awaiter(this, void 0, void 0, function* () { try {
try { const cache = core.getInput('cache');
const cache = core.getInput('cache'); if (cache) {
if (cache) { await saveCache(cache);
yield saveCache(cache); if (earlyExit) {
if (earlyExit) { process.exit(0);
process.exit(0);
}
} }
} }
catch (error) { }
const err = error; catch (error) {
core.setFailed(err.message); const err = error;
} core.setFailed(err.message);
}); }
} }
exports.run = run; async function saveCache(packageManager) {
function saveCache(packageManager) { const cachePathState = core.getState(cache_distributor_1.State.CACHE_PATHS);
return __awaiter(this, void 0, void 0, function* () { if (!cachePathState) {
const cachePathState = core.getState(cache_distributor_1.State.CACHE_PATHS); core.warning('Cache paths are empty. Please check the previous logs and make sure that the python version is specified');
if (!cachePathState) { return;
core.warning('Cache paths are empty. Please check the previous logs and make sure that the python version is specified'); }
return; const cachePaths = JSON.parse(cachePathState);
} core.debug(`paths for caching are ${cachePaths.join(', ')}`);
const cachePaths = JSON.parse(cachePathState); if (!isCacheDirectoryExists(cachePaths)) {
core.debug(`paths for caching are ${cachePaths.join(', ')}`); core.warning(`Cache folder path is retrieved for ${packageManager} but doesn't exist on disk: ${cachePaths.join(', ')}. This likely indicates that there are no dependencies to cache. Consider removing the cache step if it is not needed.`);
if (!isCacheDirectoryExists(cachePaths)) { return;
core.warning(`Cache folder path is retrieved for ${packageManager} but doesn't exist on disk: ${cachePaths.join(', ')}. This likely indicates that there are no dependencies to cache. Consider removing the cache step if it is not needed.`); }
return; const primaryKey = core.getState(cache_distributor_1.State.STATE_CACHE_PRIMARY_KEY);
} const matchedKey = core.getState(cache_distributor_1.State.CACHE_MATCHED_KEY);
const primaryKey = core.getState(cache_distributor_1.State.STATE_CACHE_PRIMARY_KEY); if (!primaryKey) {
const matchedKey = core.getState(cache_distributor_1.State.CACHE_MATCHED_KEY); core.warning('Error retrieving key from state.');
if (!primaryKey) { return;
core.warning('Error retrieving key from state.'); }
return; else if (matchedKey === primaryKey) {
} // no change in target directories
else if (matchedKey === primaryKey) { core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
// no change in target directories return;
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`); }
return; let cacheId = 0;
} try {
let cacheId = 0; cacheId = await cache.saveCache(cachePaths, primaryKey);
try { }
cacheId = yield cache.saveCache(cachePaths, primaryKey); catch (err) {
} const message = err.message;
catch (err) { core.info(`[warning]${message}`);
const message = err.message; return;
core.info(`[warning]${message}`); }
return; if (cacheId == -1) {
} return;
if (cacheId == -1) { }
return; core.info(`Cache saved with the key: ${primaryKey}`);
}
core.info(`Cache saved with the key: ${primaryKey}`);
});
} }
function isCacheDirectoryExists(cacheDirectory) { function isCacheDirectoryExists(cacheDirectory) {
const result = cacheDirectory.reduce((previousValue, currentValue) => { const result = cacheDirectory.reduce((previousValue, currentValue) => {

2016
dist/setup/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@
- [Hosted tool cache](advanced-usage.md#hosted-tool-cache) - [Hosted tool cache](advanced-usage.md#hosted-tool-cache)
- [Using `setup-python` with a self-hosted runner](advanced-usage.md#using-setup-python-with-a-self-hosted-runner) - [Using `setup-python` with a self-hosted runner](advanced-usage.md#using-setup-python-with-a-self-hosted-runner)
- [Windows](advanced-usage.md#windows) - [Windows](advanced-usage.md#windows)
- [Linux](advanced-usage.md#linux) - [Ubuntu](advanced-usage.md#Ubuntu)
- [macOS](advanced-usage.md#macos) - [macOS](advanced-usage.md#macos)
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes) - [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
- [Allow pre-releases](advanced-usage.md#allow-pre-releases) - [Allow pre-releases](advanced-usage.md#allow-pre-releases)
@ -578,9 +578,9 @@ If you have a supported self-hosted runner and you would like to use `setup-pyth
>If you are experiencing problems while configuring Python on your self-hosted runner, turn on [step debugging](https://github.com/actions/toolkit/blob/main/docs/action-debugging.md#step-debug-logs) to see additional logs. >If you are experiencing problems while configuring Python on your self-hosted runner, turn on [step debugging](https://github.com/actions/toolkit/blob/main/docs/action-debugging.md#step-debug-logs) to see additional logs.
### Linux ### Ubuntu
By default, the runner downloads and installs tools into the folder set up by `RUNNER_TOOL_CACHE` environment variable. The environment variable called `AGENT_TOOLSDIRECTORY` can be set to change this location for Linux self-hosted runners: By default, the runner downloads and installs tools into the folder set up by `RUNNER_TOOL_CACHE` environment variable. The environment variable called `AGENT_TOOLSDIRECTORY` can be set to change this location for Ubuntu self-hosted runners:
- In the same shell that your runner is using, type `export AGENT_TOOLSDIRECTORY=/path/to/folder`. - In the same shell that your runner is using, type `export AGENT_TOOLSDIRECTORY=/path/to/folder`.
- More permanent way of setting the environment variable is to create an `.env` file in the same directory as your runner and to add `AGENT_TOOLSDIRECTORY=/path/to/folder`. This ensures the variable is always set if your runner is configured as a service. - More permanent way of setting the environment variable is to create an `.env` file in the same directory as your runner and to add `AGENT_TOOLSDIRECTORY=/path/to/folder`. This ensures the variable is always set if your runner is configured as a service.
@ -690,5 +690,3 @@ The `pip-install` input allows you to install dependencies as part of the Python
``` ```
> Note: This feature is intended for standard pip-based dependency installations. > Note: This feature is intended for standard pip-based dependency installations.
For complex workflows, or alternative package managers (e.g., poetry, pipenv), we recommend using separate steps to maintain clarity and flexibility. For complex workflows, or alternative package managers (e.g., poetry, pipenv), we recommend using separate steps to maintain clarity and flexibility.
> The `pip-install` input mirrors the flexibility of a standard pip install command and supports most of its arguments.

17
package-lock.json generated
View File

@ -32,9 +32,9 @@
"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",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"ts-jest": "^29.3.2", "ts-jest": "^29.3.2",
"typescript": "^5.4.2" "typescript": "^5.9.3"
}, },
"engines": { "engines": {
"node": ">=24.0.0" "node": ">=24.0.0"
@ -4816,9 +4816,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "3.5.3", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -5446,10 +5446,11 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.4.2", "version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true, "dev": true,
"license": "Apache-2.0",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"

View File

@ -51,8 +51,8 @@
"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",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"ts-jest": "^29.3.2", "ts-jest": "^29.3.2",
"typescript": "^5.4.2" "typescript": "^5.9.3"
} }
} }

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.
*/ */

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
/* Basic Options */ /* Basic Options */
// "incremental": true, /* Enable incremental compilation */ // "incremental": true, /* Enable incremental compilation */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "target": "ES2022", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "allowJs": true, /* Allow javascript files to be compiled. */ // "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */ // "checkJs": true, /* Report errors in .js files. */