mirror of
https://github.com/actions/setup-python.git
synced 2026-07-18 06:19:58 +08:00
Merge branch 'main' into latestdep
This commit is contained in:
commit
e0228120e2
11 changed files with 236 additions and 269 deletions
59
.github/workflows/e2e-cache-freethreaded.yml
vendored
59
.github/workflows/e2e-cache-freethreaded.yml
vendored
|
|
@ -257,62 +257,3 @@ jobs:
|
|||
pip-version: '25.0.1'
|
||||
- name: Install dependencies
|
||||
run: pip install numpy pandas requests
|
||||
|
||||
python-pip-dependencies-caching-with-pip-install:
|
||||
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
[
|
||||
ubuntu-22.04,
|
||||
ubuntu-latest,
|
||||
ubuntu-24.04-arm,
|
||||
windows-latest,
|
||||
windows-11-arm,
|
||||
macos-15-intel,
|
||||
macos-latest
|
||||
]
|
||||
python-version: [3.13.14t, 3.14.6t]
|
||||
exclude:
|
||||
- os: windows-11-arm
|
||||
python-version: 3.13.14t
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
pip-install: numpy pandas requests
|
||||
|
||||
python-pip-dependencies-caching-path-with-pip-install:
|
||||
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
[
|
||||
ubuntu-22.04,
|
||||
ubuntu-latest,
|
||||
ubuntu-24.04-arm,
|
||||
windows-latest,
|
||||
windows-11-arm,
|
||||
macos-15-intel,
|
||||
macos-latest
|
||||
]
|
||||
python-version: [3.13.14t, 3.14.6t]
|
||||
exclude:
|
||||
- os: windows-11-arm
|
||||
python-version: 3.13.14t
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: __tests__/data/requirements.txt
|
||||
pip-install: numpy pandas requests
|
||||
|
|
|
|||
59
.github/workflows/e2e-cache.yml
vendored
59
.github/workflows/e2e-cache.yml
vendored
|
|
@ -300,62 +300,3 @@ jobs:
|
|||
pip-version: '25.0.1'
|
||||
- name: Install dependencies
|
||||
run: pip install numpy pandas requests
|
||||
|
||||
python-pip-dependencies-caching-with-pip-install:
|
||||
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
[
|
||||
ubuntu-22.04,
|
||||
ubuntu-latest,
|
||||
ubuntu-24.04-arm,
|
||||
windows-latest,
|
||||
windows-11-arm,
|
||||
macos-15-intel,
|
||||
macos-latest
|
||||
]
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
|
||||
exclude:
|
||||
- os: windows-11-arm
|
||||
python-version: '3.10'
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
pip-install: numpy pandas requests
|
||||
|
||||
python-pip-dependencies-caching-path-with-pip-install:
|
||||
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }}, caching path)
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
[
|
||||
ubuntu-22.04,
|
||||
ubuntu-latest,
|
||||
ubuntu-24.04-arm,
|
||||
windows-latest,
|
||||
windows-11-arm,
|
||||
macos-15-intel,
|
||||
macos-latest
|
||||
]
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
|
||||
exclude:
|
||||
- os: windows-11-arm
|
||||
python-version: '3.10'
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: __tests__/data/requirements.txt
|
||||
pip-install: numpy pandas requests
|
||||
|
|
|
|||
2
.licenses/npm/@actions/cache.dep.yml
generated
2
.licenses/npm/@actions/cache.dep.yml
generated
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: "@actions/cache"
|
||||
version: 6.1.0
|
||||
version: 6.2.0
|
||||
type: npm
|
||||
summary: Actions cache lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
||||
|
|
|
|||
|
|
@ -122,7 +122,6 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet
|
|||
- [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes)
|
||||
- [Allow pre-releases](docs/advanced-usage.md#allow-pre-releases)
|
||||
- [Using the pip-version input](docs/advanced-usage.md#using-the-pip-version-input)
|
||||
- [Using the pip-install input](docs/advanced-usage.md#using-the-pip-install-input)
|
||||
|
||||
## Recommended permissions
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ inputs:
|
|||
default: false
|
||||
pip-version:
|
||||
description: "Used to specify the version of pip to install with the Python. Supported format: major[.minor][.patch]."
|
||||
pip-install:
|
||||
description: "Used to specify the packages to install with pip after setting up Python. Can be a requirements file or package names."
|
||||
outputs:
|
||||
python-version:
|
||||
description: "The installed Python or PyPy version. Useful when given a version range as input."
|
||||
|
|
|
|||
144
dist/cache-save/index.js
vendored
144
dist/cache-save/index.js
vendored
|
|
@ -41200,7 +41200,7 @@ module.exports = { version: packageJson.version }
|
|||
/***/ 4012:
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.1.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.2.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
|
||||
/***/ })
|
||||
|
||||
|
|
@ -45451,6 +45451,10 @@ const SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32
|
|||
const TarFilename = 'cache.tar';
|
||||
const ManifestFilename = 'manifest.txt';
|
||||
const CacheFileSizeLimit = 10 * Math.pow(1024, 3); // 10GiB per repository
|
||||
// Prefix the cache backend embeds in a read-denial message (v2 twirp
|
||||
// GetCacheEntryDownloadURL error or the GHES v1 `_apis/artifactcache` 403 body).
|
||||
// Shared so cache.ts and cacheHttpClient.ts match the same contract value.
|
||||
const constants_CacheReadDeniedMessagePrefix = 'cache read denied:';
|
||||
//# sourceMappingURL=constants.js.map
|
||||
;// CONCATENATED MODULE: ./node_modules/@actions/cache/lib/internal/cacheUtils.js
|
||||
var cacheUtils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
|
|
@ -95156,6 +95160,24 @@ function config_getCacheServiceVersion() {
|
|||
return 'v1';
|
||||
return process.env['ACTIONS_CACHE_SERVICE_V2'] ? 'v2' : 'v1';
|
||||
}
|
||||
// The cache-mode lattice: readable = {read, write}, writable = {write,
|
||||
// write-only}, none = neither.
|
||||
const KNOWN_CACHE_MODES = ['none', 'read', 'write', 'write-only'];
|
||||
// The effective cache-mode exported by the runner, or '' when not set.
|
||||
function config_getCacheMode() {
|
||||
return (process.env['ACTIONS_CACHE_MODE'] || '').trim().toLowerCase();
|
||||
}
|
||||
// Unset or unrecognized modes are permissive so behavior matches today.
|
||||
function config_isCacheReadable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'read' || mode === 'write';
|
||||
}
|
||||
function isCacheWritable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'write' || mode === 'write-only';
|
||||
}
|
||||
function getCacheServiceURL() {
|
||||
const version = config_getCacheServiceVersion();
|
||||
// Based on the version of the cache service, we will determine which
|
||||
|
|
@ -95205,6 +95227,7 @@ var cacheHttpClient_awaiter = (undefined && undefined.__awaiter) || function (th
|
|||
|
||||
|
||||
|
||||
|
||||
function getCacheApiUrl(resource) {
|
||||
const baseUrl = getCacheServiceURL();
|
||||
if (!baseUrl) {
|
||||
|
|
@ -95232,6 +95255,7 @@ function createHttpClient() {
|
|||
}
|
||||
function getCacheEntry(keys, paths, options) {
|
||||
return cacheHttpClient_awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
const httpClient = createHttpClient();
|
||||
const version = utils.getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod, options === null || options === void 0 ? void 0 : options.enableCrossOsArchive);
|
||||
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
|
||||
|
|
@ -95245,6 +95269,12 @@ function getCacheEntry(keys, paths, options) {
|
|||
return null;
|
||||
}
|
||||
if (!isSuccessStatusCode(response.statusCode)) {
|
||||
// Only surface the receiver's body for a `cache read denied:` policy denial
|
||||
// so callers can dispatch on it; keep the generic message otherwise.
|
||||
const errorMessage = (_a = response.error) === null || _a === void 0 ? void 0 : _a.message;
|
||||
if (errorMessage === null || errorMessage === void 0 ? void 0 : errorMessage.includes(CacheReadDeniedMessagePrefix)) {
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
const cacheResult = response.result;
|
||||
|
|
@ -96505,6 +96535,7 @@ var cache_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
|||
|
||||
|
||||
|
||||
|
||||
class ValidationError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
|
|
@ -96520,19 +96551,20 @@ class ReserveCacheError extends Error {
|
|||
}
|
||||
}
|
||||
/**
|
||||
* Stable prefix the receiver writes into the cache reservation response when
|
||||
* the issuer downgraded the cache token to read-only (for example, because
|
||||
* Stable prefix the cache service writes into the cache reservation response
|
||||
* when the issuer downgraded the cache token to read-only (for example, because
|
||||
* the run was triggered by an untrusted event). saveCacheV1 / saveCacheV2
|
||||
* dispatch on this prefix to re-classify the failure as a
|
||||
* CacheWriteDeniedError so consumers (and the outer catch arm) can
|
||||
* distinguish a policy denial from other reservation failures.
|
||||
* dispatch on this prefix to re-classify the failure as a CacheWriteDeniedError
|
||||
* so consumers and tests can distinguish a policy denial from other reservation
|
||||
* failures. Internally it is logged as a non-fatal warning like other
|
||||
* best-effort save failures.
|
||||
*/
|
||||
const CACHE_WRITE_DENIED_PREFIX = 'cache write denied:';
|
||||
/**
|
||||
* Raised when the cache backend refuses to reserve a writable cache entry
|
||||
* because the JWT issued for this run was scoped read-only (for example, the
|
||||
* run was triggered by an event the repository administrator classified as
|
||||
* untrusted). The receiver-supplied detail message always begins with
|
||||
* untrusted). The service-supplied detail message always begins with
|
||||
* `cache write denied:` (the full error message includes additional context
|
||||
* like the cache key).
|
||||
*
|
||||
|
|
@ -96548,6 +96580,19 @@ class CacheWriteDeniedError extends ReserveCacheError {
|
|||
Object.setPrototypeOf(this, CacheWriteDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
// Re-exported from constants so consumers keep referencing it here; the shared
|
||||
// value also drives detection in cacheHttpClient without duplicating the string.
|
||||
const CACHE_READ_DENIED_PREFIX = (/* unused pure expression or super */ null && (CacheReadDeniedMessagePrefix));
|
||||
// Raised when the cache backend denies a download URL because the run's token
|
||||
// has no readable cache scopes. Caching is best-effort, so restoreCache logs a
|
||||
// warning and reports a cache miss rather than rethrowing this.
|
||||
class CacheReadDeniedError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'CacheReadDeniedError';
|
||||
Object.setPrototypeOf(this, CacheReadDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
class FinalizeCacheError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
|
|
@ -96602,6 +96647,12 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
const cacheServiceVersion = getCacheServiceVersion();
|
||||
core.debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
const cacheMode = getCacheMode();
|
||||
if (!isCacheReadable(cacheMode)) {
|
||||
core.info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`);
|
||||
core.debug(`Skipped restore for paths [${paths.join(', ')}] with primary key '${primaryKey}'.`);
|
||||
return undefined;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield restoreCacheV2(paths, primaryKey, restoreKeys, options, enableCrossOsArchive);
|
||||
|
|
@ -96623,6 +96674,7 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
*/
|
||||
function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
restoreKeys = restoreKeys || [];
|
||||
const keys = [primaryKey, ...restoreKeys];
|
||||
core.debug('Resolved Keys:');
|
||||
|
|
@ -96637,10 +96689,26 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
let archivePath = '';
|
||||
try {
|
||||
// path are needed to compute version
|
||||
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
let cacheEntry;
|
||||
try {
|
||||
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
// The v1 artifact cache service returns HTTP 403 with a
|
||||
// `cache read denied:` body when the run's token has no readable cache
|
||||
// scopes. getCacheEntry lives in a dependency-free internal module and
|
||||
// cannot import CacheReadDeniedError without a circular dependency, so it
|
||||
// only surfaces the raw denial message; we classify it into the typed
|
||||
// error here so the outer catch and consumers can dispatch on it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||
// Cache not found
|
||||
return undefined;
|
||||
|
|
@ -96669,7 +96737,9 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
}
|
||||
else {
|
||||
// warn on cache restore failure and continue build
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
@ -96704,6 +96774,7 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
*/
|
||||
function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
// Override UploadOptions to force the use of Azure
|
||||
options = Object.assign(Object.assign({}, options), { useAzureSdk: true });
|
||||
restoreKeys = restoreKeys || [];
|
||||
|
|
@ -96725,7 +96796,20 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
restoreKeys,
|
||||
version: utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive)
|
||||
};
|
||||
const response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
let response;
|
||||
try {
|
||||
response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
}
|
||||
catch (error) {
|
||||
// The receiver returns twirp PermissionDenied (403) when the run's token
|
||||
// has no readable cache scopes. The client wraps that 403, so the stable
|
||||
// prefix is embedded in the message rather than leading it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!response.ok) {
|
||||
core.debug(`Cache not found for version ${request.version} of keys: ${keys.join(', ')}`);
|
||||
return undefined;
|
||||
|
|
@ -96760,8 +96844,10 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
throw error;
|
||||
}
|
||||
else {
|
||||
// Supress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Suppress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
@ -96800,6 +96886,12 @@ function cache_saveCache(paths_1, key_1, options_1) {
|
|||
core_debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
checkKey(key);
|
||||
const cacheMode = config_getCacheMode();
|
||||
if (!isCacheWritable(cacheMode)) {
|
||||
info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`);
|
||||
core_debug(`Skipped save for paths [${paths.join(', ')}] with key '${key}'.`);
|
||||
return -1;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield saveCacheV2(paths, key, options, enableCrossOsArchive);
|
||||
|
|
@ -96877,17 +96969,14 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
|||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
@ -96998,12 +97087,6 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
|||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
|
|
@ -97011,7 +97094,10 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
|||
warning(typedError.message);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
|
|||
160
dist/setup/index.js
vendored
160
dist/setup/index.js
vendored
|
|
@ -41200,7 +41200,7 @@ module.exports = { version: packageJson.version }
|
|||
/***/ 4012:
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.1.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.2.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
|
||||
/***/ })
|
||||
|
||||
|
|
@ -45441,6 +45441,10 @@ const SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32
|
|||
const TarFilename = 'cache.tar';
|
||||
const constants_ManifestFilename = 'manifest.txt';
|
||||
const CacheFileSizeLimit = 10 * Math.pow(1024, 3); // 10GiB per repository
|
||||
// Prefix the cache backend embeds in a read-denial message (v2 twirp
|
||||
// GetCacheEntryDownloadURL error or the GHES v1 `_apis/artifactcache` 403 body).
|
||||
// Shared so cache.ts and cacheHttpClient.ts match the same contract value.
|
||||
const CacheReadDeniedMessagePrefix = 'cache read denied:';
|
||||
//# sourceMappingURL=constants.js.map
|
||||
;// CONCATENATED MODULE: ./node_modules/@actions/cache/lib/internal/cacheUtils.js
|
||||
var cacheUtils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
|
|
@ -95147,6 +95151,24 @@ function config_getCacheServiceVersion() {
|
|||
return 'v1';
|
||||
return process.env['ACTIONS_CACHE_SERVICE_V2'] ? 'v2' : 'v1';
|
||||
}
|
||||
// The cache-mode lattice: readable = {read, write}, writable = {write,
|
||||
// write-only}, none = neither.
|
||||
const KNOWN_CACHE_MODES = ['none', 'read', 'write', 'write-only'];
|
||||
// The effective cache-mode exported by the runner, or '' when not set.
|
||||
function config_getCacheMode() {
|
||||
return (process.env['ACTIONS_CACHE_MODE'] || '').trim().toLowerCase();
|
||||
}
|
||||
// Unset or unrecognized modes are permissive so behavior matches today.
|
||||
function isCacheReadable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'read' || mode === 'write';
|
||||
}
|
||||
function config_isCacheWritable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'write' || mode === 'write-only';
|
||||
}
|
||||
function getCacheServiceURL() {
|
||||
const version = config_getCacheServiceVersion();
|
||||
// Based on the version of the cache service, we will determine which
|
||||
|
|
@ -95196,6 +95218,7 @@ var cacheHttpClient_awaiter = (undefined && undefined.__awaiter) || function (th
|
|||
|
||||
|
||||
|
||||
|
||||
function getCacheApiUrl(resource) {
|
||||
const baseUrl = getCacheServiceURL();
|
||||
if (!baseUrl) {
|
||||
|
|
@ -95223,6 +95246,7 @@ function createHttpClient() {
|
|||
}
|
||||
function getCacheEntry(keys, paths, options) {
|
||||
return cacheHttpClient_awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
const httpClient = createHttpClient();
|
||||
const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod, options === null || options === void 0 ? void 0 : options.enableCrossOsArchive);
|
||||
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
|
||||
|
|
@ -95236,6 +95260,12 @@ function getCacheEntry(keys, paths, options) {
|
|||
return null;
|
||||
}
|
||||
if (!requestUtils_isSuccessStatusCode(response.statusCode)) {
|
||||
// Only surface the receiver's body for a `cache read denied:` policy denial
|
||||
// so callers can dispatch on it; keep the generic message otherwise.
|
||||
const errorMessage = (_a = response.error) === null || _a === void 0 ? void 0 : _a.message;
|
||||
if (errorMessage === null || errorMessage === void 0 ? void 0 : errorMessage.includes(CacheReadDeniedMessagePrefix)) {
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
const cacheResult = response.result;
|
||||
|
|
@ -96497,6 +96527,7 @@ var cache_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
|||
|
||||
|
||||
|
||||
|
||||
class ValidationError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
|
|
@ -96512,19 +96543,20 @@ class ReserveCacheError extends Error {
|
|||
}
|
||||
}
|
||||
/**
|
||||
* Stable prefix the receiver writes into the cache reservation response when
|
||||
* the issuer downgraded the cache token to read-only (for example, because
|
||||
* Stable prefix the cache service writes into the cache reservation response
|
||||
* when the issuer downgraded the cache token to read-only (for example, because
|
||||
* the run was triggered by an untrusted event). saveCacheV1 / saveCacheV2
|
||||
* dispatch on this prefix to re-classify the failure as a
|
||||
* CacheWriteDeniedError so consumers (and the outer catch arm) can
|
||||
* distinguish a policy denial from other reservation failures.
|
||||
* dispatch on this prefix to re-classify the failure as a CacheWriteDeniedError
|
||||
* so consumers and tests can distinguish a policy denial from other reservation
|
||||
* failures. Internally it is logged as a non-fatal warning like other
|
||||
* best-effort save failures.
|
||||
*/
|
||||
const CACHE_WRITE_DENIED_PREFIX = 'cache write denied:';
|
||||
/**
|
||||
* Raised when the cache backend refuses to reserve a writable cache entry
|
||||
* because the JWT issued for this run was scoped read-only (for example, the
|
||||
* run was triggered by an event the repository administrator classified as
|
||||
* untrusted). The receiver-supplied detail message always begins with
|
||||
* untrusted). The service-supplied detail message always begins with
|
||||
* `cache write denied:` (the full error message includes additional context
|
||||
* like the cache key).
|
||||
*
|
||||
|
|
@ -96540,6 +96572,19 @@ class CacheWriteDeniedError extends ReserveCacheError {
|
|||
Object.setPrototypeOf(this, CacheWriteDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
// Re-exported from constants so consumers keep referencing it here; the shared
|
||||
// value also drives detection in cacheHttpClient without duplicating the string.
|
||||
const CACHE_READ_DENIED_PREFIX = CacheReadDeniedMessagePrefix;
|
||||
// Raised when the cache backend denies a download URL because the run's token
|
||||
// has no readable cache scopes. Caching is best-effort, so restoreCache logs a
|
||||
// warning and reports a cache miss rather than rethrowing this.
|
||||
class CacheReadDeniedError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'CacheReadDeniedError';
|
||||
Object.setPrototypeOf(this, CacheReadDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
class FinalizeCacheError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
|
|
@ -96594,6 +96639,12 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
const cacheServiceVersion = config_getCacheServiceVersion();
|
||||
core_debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
const cacheMode = config_getCacheMode();
|
||||
if (!isCacheReadable(cacheMode)) {
|
||||
info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`);
|
||||
core_debug(`Skipped restore for paths [${paths.join(', ')}] with primary key '${primaryKey}'.`);
|
||||
return undefined;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield restoreCacheV2(paths, primaryKey, restoreKeys, options, enableCrossOsArchive);
|
||||
|
|
@ -96615,6 +96666,7 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
*/
|
||||
function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
restoreKeys = restoreKeys || [];
|
||||
const keys = [primaryKey, ...restoreKeys];
|
||||
core_debug('Resolved Keys:');
|
||||
|
|
@ -96629,10 +96681,26 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
let archivePath = '';
|
||||
try {
|
||||
// path are needed to compute version
|
||||
const cacheEntry = yield getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
let cacheEntry;
|
||||
try {
|
||||
cacheEntry = yield getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
// The v1 artifact cache service returns HTTP 403 with a
|
||||
// `cache read denied:` body when the run's token has no readable cache
|
||||
// scopes. getCacheEntry lives in a dependency-free internal module and
|
||||
// cannot import CacheReadDeniedError without a circular dependency, so it
|
||||
// only surfaces the raw denial message; we classify it into the typed
|
||||
// error here so the outer catch and consumers can dispatch on it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||
// Cache not found
|
||||
return undefined;
|
||||
|
|
@ -96661,7 +96729,9 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
}
|
||||
else {
|
||||
// warn on cache restore failure and continue build
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
@ -96696,6 +96766,7 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
*/
|
||||
function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
// Override UploadOptions to force the use of Azure
|
||||
options = Object.assign(Object.assign({}, options), { useAzureSdk: true });
|
||||
restoreKeys = restoreKeys || [];
|
||||
|
|
@ -96717,7 +96788,20 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
restoreKeys,
|
||||
version: getCacheVersion(paths, compressionMethod, enableCrossOsArchive)
|
||||
};
|
||||
const response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
let response;
|
||||
try {
|
||||
response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
}
|
||||
catch (error) {
|
||||
// The receiver returns twirp PermissionDenied (403) when the run's token
|
||||
// has no readable cache scopes. The client wraps that 403, so the stable
|
||||
// prefix is embedded in the message rather than leading it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!response.ok) {
|
||||
core_debug(`Cache not found for version ${request.version} of keys: ${keys.join(', ')}`);
|
||||
return undefined;
|
||||
|
|
@ -96752,8 +96836,10 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
|||
throw error;
|
||||
}
|
||||
else {
|
||||
// Supress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Suppress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
@ -96792,6 +96878,12 @@ function cache_saveCache(paths_1, key_1, options_1) {
|
|||
core.debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
checkKey(key);
|
||||
const cacheMode = getCacheMode();
|
||||
if (!isCacheWritable(cacheMode)) {
|
||||
core.info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`);
|
||||
core.debug(`Skipped save for paths [${paths.join(', ')}] with key '${key}'.`);
|
||||
return -1;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield saveCacheV2(paths, key, options, enableCrossOsArchive);
|
||||
|
|
@ -96869,17 +96961,14 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
|||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
@ -96990,12 +97079,6 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
|||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
|
|
@ -97003,7 +97086,10 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
|||
core.warning(typedError.message);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
|
|
@ -102864,24 +102950,12 @@ function getCacheDistributor(packageManager, pythonVersion, cacheDependencyPath)
|
|||
|
||||
|
||||
|
||||
|
||||
function isPyPyVersion(versionSpec) {
|
||||
return versionSpec.startsWith('pypy');
|
||||
}
|
||||
function isGraalPyVersion(versionSpec) {
|
||||
return versionSpec.startsWith('graalpy');
|
||||
}
|
||||
async function installPipPackages(pipInstall) {
|
||||
info(`Installing pip packages: ${pipInstall}`);
|
||||
try {
|
||||
const installArgs = pipInstall.trim().split(/\s+/);
|
||||
await exec_exec('python', ['-m', 'pip', 'install', ...installArgs]);
|
||||
info('Successfully installed pip packages');
|
||||
}
|
||||
catch {
|
||||
setFailed(`Failed to install pip packages from "${pipInstall}". Please verify that the package names, versions, or requirements files provided are correct and installable, that the specified packages and versions can be resolved from PyPI or the configured package index, and that your network connection is stable and allows access to the package index.`);
|
||||
}
|
||||
}
|
||||
async function cacheDependencies(cache, pythonVersion) {
|
||||
const cacheDependencyPath = getInput('cache-dependency-path') || undefined;
|
||||
const cacheDistributor = getCacheDistributor(cache, pythonVersion, cacheDependencyPath);
|
||||
|
|
@ -102966,10 +103040,6 @@ async function run() {
|
|||
if (cache && isCacheFeatureAvailable()) {
|
||||
await cacheDependencies(cache, pythonVersion);
|
||||
}
|
||||
const pipInstall = getInput('pip-install');
|
||||
if (pipInstall) {
|
||||
await installPipPackages(pipInstall);
|
||||
}
|
||||
}
|
||||
else {
|
||||
warning('The `python-version` input is not set. The version of Python currently in `PATH` will be used.');
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
|
||||
- [Allow pre-releases](advanced-usage.md#allow-pre-releases)
|
||||
- [Using the pip-version input](advanced-usage.md#using-the-pip-version-input)
|
||||
- [Using the pip-install input](advanced-usage.md#using-the-pip-install-input)
|
||||
|
||||
## Using the `python-version` input
|
||||
|
||||
|
|
@ -673,22 +672,3 @@ The version of Pip should be specified in the format `major`, `major.minor`, or
|
|||
> The `pip-version` input is supported only with standard Python versions. It is not available when using PyPy or GraalPy.
|
||||
|
||||
> Using a specific or outdated version of pip may result in compatibility or security issues and can cause job failures. For best practices and guidance, refer to the official [pip documentation](https://pip.pypa.io/en/stable/).
|
||||
|
||||
## Using the pip-install input
|
||||
|
||||
The `pip-install` input allows you to install dependencies as part of the Python setup step.
|
||||
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: '3.13'
|
||||
pip-install: -r requirements.txt
|
||||
```
|
||||
> 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.
|
||||
|
||||
> The `pip-install` input mirrors the flexibility of a standard pip install command and supports most of its arguments.
|
||||
|
|
|
|||
38
package-lock.json
generated
38
package-lock.json
generated
|
|
@ -9,7 +9,7 @@
|
|||
"version": "7.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^6.1.0",
|
||||
"@actions/cache": "^6.2.0",
|
||||
"@actions/core": "^3.0.1",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/glob": "^0.7.0",
|
||||
|
|
@ -42,9 +42,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@actions/cache": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.1.0.tgz",
|
||||
"integrity": "sha512-LVqybSbzhBp2uAETOQ3HnVjXA4AcjavgMH+LCr+cjgO+PZfciv/1QAgoW+esXBaAhvDid+vXeV70GGJpAh4V5Q==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.2.0.tgz",
|
||||
"integrity": "sha512-Nv0xWRmbxfDbAn/70flO/F6tj2Nv4XTYMAsQHiDFSojCDfso/Zni+fRKa14ToI9hnmOW/rQcY1WYb6wsM7Pgwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^3.0.1",
|
||||
|
|
@ -2197,9 +2197,6 @@
|
|||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2214,9 +2211,6 @@
|
|||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2231,9 +2225,6 @@
|
|||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2248,9 +2239,6 @@
|
|||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2265,9 +2253,6 @@
|
|||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2282,9 +2267,6 @@
|
|||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2299,9 +2281,6 @@
|
|||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2316,9 +2295,6 @@
|
|||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2333,9 +2309,6 @@
|
|||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
@ -2350,9 +2323,6 @@
|
|||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^6.1.0",
|
||||
"@actions/cache": "^6.2.0",
|
||||
"@actions/core": "^3.0.1",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/glob": "^0.7.0",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import {
|
|||
getVersionInputFromFile,
|
||||
getVersionsInputFromPlainFile
|
||||
} from './utils.js';
|
||||
import {exec} from '@actions/exec';
|
||||
|
||||
function isPyPyVersion(versionSpec: string) {
|
||||
return versionSpec.startsWith('pypy');
|
||||
|
|
@ -24,19 +23,6 @@ function isGraalPyVersion(versionSpec: string) {
|
|||
return versionSpec.startsWith('graalpy');
|
||||
}
|
||||
|
||||
async function installPipPackages(pipInstall: string) {
|
||||
core.info(`Installing pip packages: ${pipInstall}`);
|
||||
try {
|
||||
const installArgs = pipInstall.trim().split(/\s+/);
|
||||
await exec('python', ['-m', 'pip', 'install', ...installArgs]);
|
||||
core.info('Successfully installed pip packages');
|
||||
} catch {
|
||||
core.setFailed(
|
||||
`Failed to install pip packages from "${pipInstall}". Please verify that the package names, versions, or requirements files provided are correct and installable, that the specified packages and versions can be resolved from PyPI or the configured package index, and that your network connection is stable and allows access to the package index.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function cacheDependencies(cache: string, pythonVersion: string) {
|
||||
const cacheDependencyPath =
|
||||
core.getInput('cache-dependency-path') || undefined;
|
||||
|
|
@ -160,10 +146,6 @@ async function run() {
|
|||
if (cache && isCacheFeatureAvailable()) {
|
||||
await cacheDependencies(cache, pythonVersion);
|
||||
}
|
||||
const pipInstall = core.getInput('pip-install');
|
||||
if (pipInstall) {
|
||||
await installPipPackages(pipInstall);
|
||||
}
|
||||
} else {
|
||||
core.warning(
|
||||
'The `python-version` input is not set. The version of Python currently in `PATH` will be used.'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue