mirror of
https://github.com/actions/setup-node.git
synced 2026-10-15 20:06:55 +00:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76757a8d01 | ||
|
|
04be95cf35 | ||
|
|
7c2c68d20d | ||
|
|
6a61c0375d | ||
|
|
30eb73b41d | ||
|
|
4e1a87a501 | ||
|
|
360237f0c0 | ||
|
|
4f8aac5beb | ||
|
|
f4a67bbeca | ||
|
|
0355742c94 | ||
|
|
ad1b57eb81 | ||
|
|
670825a89d |
No files matched your search
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
Binary file not shown.
Generated
BIN
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@@ -119,6 +119,7 @@ steps:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -217,6 +218,7 @@ jobs:
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -232,6 +234,7 @@ uses: actions/setup-node@v6
|
||||
with:
|
||||
token: ${{ secrets.GH_DOTCOM_TOKEN }}
|
||||
node-version: 24
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
```
|
||||
|
||||
If the runner is not able to access github.com, any Nodejs versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.
|
||||
@@ -249,6 +252,7 @@ If the runner is not able to access github.com, any Nodejs versions requested du
|
||||
- [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm)
|
||||
- [Publishing to npmjs and GPR with yarn](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-yarn)
|
||||
- [Using private packages](docs/advanced-usage.md#use-private-packages)
|
||||
- [Publishing to npm with Trusted Publisher (OIDC)](docs/advanced-usage.md#publishing-to-npm-with-trusted-publisher-oidc)
|
||||
- [Using private mirror](docs/advanced-usage.md#use-private-mirror)
|
||||
|
||||
## Recommended permissions
|
||||
|
||||
@@ -118,6 +118,27 @@ describe('authutil tests', () => {
|
||||
expect(process.env.NODE_AUTH_TOKEN).toEqual('foobar');
|
||||
});
|
||||
|
||||
it('should not export NODE_AUTH_TOKEN if not set in environment', async () => {
|
||||
const exportSpy = jest.spyOn(core, 'exportVariable');
|
||||
delete process.env.NODE_AUTH_TOKEN;
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
const rc = readRcFile(rcFile);
|
||||
expect(rc['registry']).toBe('https://registry.npmjs.org/');
|
||||
expect(exportSpy).not.toHaveBeenCalledWith(
|
||||
'NODE_AUTH_TOKEN',
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
|
||||
it('should export NODE_AUTH_TOKEN if set to empty string', async () => {
|
||||
const exportSpy = jest.spyOn(core, 'exportVariable');
|
||||
process.env.NODE_AUTH_TOKEN = '';
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
expect(exportSpy).toHaveBeenCalledWith('NODE_AUTH_TOKEN', '');
|
||||
});
|
||||
|
||||
it('configAuthentication should overwrite non-scoped with non-scoped', async () => {
|
||||
fs.writeFileSync(rcFile, 'registry=NNN');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
|
||||
@@ -137,6 +137,7 @@ describe('cache-restore', () => {
|
||||
] as const)(
|
||||
'restored dependencies for %s',
|
||||
async (packageManager, toolVersion, fileHash) => {
|
||||
const expectedCacheKey = `node-cache-${platform}-${arch}-${packageManager}-${fileHash}`;
|
||||
// Set workspace to the appropriate fixture folder
|
||||
setWorkspaceFor(packageManager);
|
||||
getCommandOutputSpy.mockImplementation((command: string) => {
|
||||
@@ -150,12 +151,20 @@ describe('cache-restore', () => {
|
||||
await restoreCache(packageManager, '');
|
||||
expect(hashFilesSpy).toHaveBeenCalled();
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
`Cache restored from key: node-cache-${platform}-${arch}-${packageManager}-${fileHash}`
|
||||
`Cache restored from key: ${expectedCacheKey}`
|
||||
);
|
||||
expect(infoSpy).not.toHaveBeenCalledWith(
|
||||
`${packageManager} cache is not found`
|
||||
);
|
||||
expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true);
|
||||
expect(setOutputSpy).toHaveBeenCalledWith(
|
||||
'cache-primary-key',
|
||||
expectedCacheKey
|
||||
);
|
||||
expect(setOutputSpy).toHaveBeenCalledWith(
|
||||
'cache-matched-key',
|
||||
expectedCacheKey
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -169,6 +178,7 @@ describe('cache-restore', () => {
|
||||
] as const)(
|
||||
'dependencies are changed %s',
|
||||
async (packageManager, toolVersion, fileHash) => {
|
||||
const expectedCacheKey = `node-cache-${platform}-${arch}-${packageManager}-${fileHash}`;
|
||||
// Set workspace to the appropriate fixture folder
|
||||
setWorkspaceFor(packageManager);
|
||||
getCommandOutputSpy.mockImplementation((command: string) => {
|
||||
@@ -186,6 +196,14 @@ describe('cache-restore', () => {
|
||||
`${packageManager} cache is not found`
|
||||
);
|
||||
expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', false);
|
||||
expect(setOutputSpy).toHaveBeenCalledWith(
|
||||
'cache-primary-key',
|
||||
expectedCacheKey
|
||||
);
|
||||
expect(setOutputSpy).toHaveBeenCalledWith(
|
||||
'cache-matched-key',
|
||||
undefined
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -343,7 +343,9 @@ describe('run', () => {
|
||||
expect(getInputSpy).not.toHaveBeenCalled();
|
||||
expect(getStateSpy).toHaveBeenCalledTimes(4);
|
||||
expect(getCommandOutputSpy).toHaveBeenCalledTimes(0);
|
||||
expect(debugSpy).toHaveBeenCalledTimes(0);
|
||||
expect(debugSpy).toHaveBeenLastCalledWith(
|
||||
`Cache was not saved for the key: ${yarnFileHash}`
|
||||
);
|
||||
expect(infoSpy).not.toHaveBeenCalledWith(
|
||||
`Cache hit occurred on the primary key ${npmFileHash}, not saving cache.`
|
||||
);
|
||||
|
||||
@@ -34,6 +34,10 @@ inputs:
|
||||
outputs:
|
||||
cache-hit:
|
||||
description: 'A boolean value to indicate if a cache was hit.'
|
||||
cache-primary-key:
|
||||
description: 'The key used to restore and save the cache.'
|
||||
cache-matched-key:
|
||||
description: 'The key of the cache that was restored. Empty when no cache is found.'
|
||||
node-version:
|
||||
description: 'The installed node version.'
|
||||
runs:
|
||||
|
||||
Vendored
+354
-116
@@ -49,7 +49,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.FinalizeCacheError = exports.ReserveCacheError = exports.ValidationError = void 0;
|
||||
exports.FinalizeCacheError = exports.CacheWriteDeniedError = exports.CACHE_WRITE_DENIED_PREFIX = exports.ReserveCacheError = exports.ValidationError = void 0;
|
||||
exports.isFeatureAvailable = isFeatureAvailable;
|
||||
exports.restoreCache = restoreCache;
|
||||
exports.saveCache = saveCache;
|
||||
@@ -77,6 +77,26 @@ class ReserveCacheError extends Error {
|
||||
}
|
||||
}
|
||||
exports.ReserveCacheError = ReserveCacheError;
|
||||
/**
|
||||
* Stable prefix used by the cache receiver to signal that the token has
|
||||
* no writable scopes (read-only cache policy). Consumers can match on
|
||||
* this prefix to distinguish policy denials from ordinary contention.
|
||||
*/
|
||||
exports.CACHE_WRITE_DENIED_PREFIX = 'cache write denied:';
|
||||
/**
|
||||
* Extends ReserveCacheError for source-compatibility: existing
|
||||
* `instanceof ReserveCacheError` checks and `typedError.name ===
|
||||
* ReserveCacheError.name` paths keep working, while consumers that want to
|
||||
* distinguish a policy denial can check for CacheWriteDeniedError.name.
|
||||
*/
|
||||
class CacheWriteDeniedError extends ReserveCacheError {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'CacheWriteDeniedError';
|
||||
Object.setPrototypeOf(this, CacheWriteDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
exports.CacheWriteDeniedError = CacheWriteDeniedError;
|
||||
class FinalizeCacheError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
@@ -387,7 +407,11 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
throw new Error((_d = (_c = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : `Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the data cap limit, not saving cache.`);
|
||||
}
|
||||
else {
|
||||
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${(_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message}`);
|
||||
const detailMessage = (_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message;
|
||||
if (detailMessage === null || detailMessage === void 0 ? void 0 : detailMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) {
|
||||
throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${detailMessage}`);
|
||||
}
|
||||
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${detailMessage}`);
|
||||
}
|
||||
core.debug(`Saving Cache (ID: ${cacheId})`);
|
||||
yield cacheHttpClient.saveCache(cacheId, archivePath, '', options);
|
||||
@@ -397,6 +421,9 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
@@ -435,6 +462,7 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
*/
|
||||
function saveCacheV2(paths_1, key_1, options_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
// Override UploadOptions to force the use of Azure
|
||||
// ...options goes first because we want to override the default values
|
||||
// set in UploadOptions with these specific figures
|
||||
@@ -470,7 +498,11 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
try {
|
||||
const response = yield twirpClient.CreateCacheEntry(request);
|
||||
if (!response.ok) {
|
||||
if (response.message) {
|
||||
// Skip the redundant inner warning when the receiver signalled a
|
||||
// policy denial: the outer catch arm below will log a single
|
||||
// customer-facing warning.
|
||||
if (response.message &&
|
||||
!response.message.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) {
|
||||
core.warning(`Cache reservation failed: ${response.message}`);
|
||||
}
|
||||
throw new Error(response.message || 'Response was not ok');
|
||||
@@ -479,6 +511,10 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
}
|
||||
catch (error) {
|
||||
core.debug(`Failed to reserve cache: ${error}`);
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) {
|
||||
throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${errorMessage}`);
|
||||
}
|
||||
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache.`);
|
||||
}
|
||||
core.debug(`Attempting to upload cache located at: ${archivePath}`);
|
||||
@@ -503,6 +539,9 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
@@ -22910,8 +22949,6 @@ function defaultFactory (origin, opts) {
|
||||
|
||||
class Agent extends DispatcherBase {
|
||||
constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
|
||||
super()
|
||||
|
||||
if (typeof factory !== 'function') {
|
||||
throw new InvalidArgumentError('factory must be a function.')
|
||||
}
|
||||
@@ -22924,6 +22961,8 @@ class Agent extends DispatcherBase {
|
||||
throw new InvalidArgumentError('maxRedirections must be a positive number')
|
||||
}
|
||||
|
||||
super(options)
|
||||
|
||||
if (connect && typeof connect !== 'function') {
|
||||
connect = { ...connect }
|
||||
}
|
||||
@@ -23297,6 +23336,9 @@ const EMPTY_BUF = Buffer.alloc(0)
|
||||
const FastBuffer = Buffer[Symbol.species]
|
||||
const addListener = util.addListener
|
||||
const removeAllListeners = util.removeAllListeners
|
||||
const kIdleSocketValidation = Symbol('kIdleSocketValidation')
|
||||
const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout')
|
||||
const kSocketUsed = Symbol('kSocketUsed')
|
||||
|
||||
let extractBody
|
||||
|
||||
@@ -23519,29 +23561,71 @@ class Parser {
|
||||
|
||||
const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr
|
||||
|
||||
if (ret === constants.ERROR.PAUSED_UPGRADE) {
|
||||
this.onUpgrade(data.slice(offset))
|
||||
} else if (ret === constants.ERROR.PAUSED) {
|
||||
this.paused = true
|
||||
socket.unshift(data.slice(offset))
|
||||
} else if (ret !== constants.ERROR.OK) {
|
||||
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
|
||||
let message = ''
|
||||
/* istanbul ignore else: difficult to make a test case for */
|
||||
if (ptr) {
|
||||
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
|
||||
message =
|
||||
'Response does not match the HTTP/1.1 protocol (' +
|
||||
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
|
||||
')'
|
||||
if (ret !== constants.ERROR.OK) {
|
||||
const body = data.subarray(offset)
|
||||
|
||||
if (ret === constants.ERROR.PAUSED_UPGRADE) {
|
||||
this.onUpgrade(body)
|
||||
} else if (ret === constants.ERROR.PAUSED) {
|
||||
this.paused = true
|
||||
socket.unshift(body)
|
||||
} else {
|
||||
throw this.createError(ret, body)
|
||||
}
|
||||
throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
|
||||
}
|
||||
} catch (err) {
|
||||
util.destroy(socket, err)
|
||||
}
|
||||
}
|
||||
|
||||
finish () {
|
||||
assert(currentParser === null)
|
||||
assert(this.ptr != null)
|
||||
assert(!this.paused)
|
||||
|
||||
const { llhttp } = this
|
||||
|
||||
let ret
|
||||
|
||||
try {
|
||||
currentParser = this
|
||||
ret = llhttp.llhttp_finish(this.ptr)
|
||||
} finally {
|
||||
currentParser = null
|
||||
}
|
||||
|
||||
if (ret === constants.ERROR.OK) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) {
|
||||
this.paused = true
|
||||
return null
|
||||
}
|
||||
|
||||
return this.createError(ret, EMPTY_BUF)
|
||||
}
|
||||
|
||||
createError (ret, data) {
|
||||
const { llhttp, contentLength, bytesRead } = this
|
||||
|
||||
if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
|
||||
return new ResponseContentLengthMismatchError()
|
||||
}
|
||||
|
||||
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
|
||||
let message = ''
|
||||
if (ptr) {
|
||||
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
|
||||
message =
|
||||
'Response does not match the HTTP/1.1 protocol (' +
|
||||
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
|
||||
')'
|
||||
}
|
||||
|
||||
return new HTTPParserError(message, constants.ERROR[ret], data)
|
||||
}
|
||||
|
||||
destroy () {
|
||||
assert(this.ptr != null)
|
||||
assert(currentParser == null)
|
||||
@@ -23569,6 +23653,11 @@ class Parser {
|
||||
return -1
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0) {
|
||||
util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
|
||||
return -1
|
||||
}
|
||||
|
||||
const request = client[kQueue][client[kRunningIdx]]
|
||||
if (!request) {
|
||||
return -1
|
||||
@@ -23672,6 +23761,11 @@ class Parser {
|
||||
return -1
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0) {
|
||||
util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
|
||||
return -1
|
||||
}
|
||||
|
||||
const request = client[kQueue][client[kRunningIdx]]
|
||||
|
||||
/* istanbul ignore next: difficult to make a test case for */
|
||||
@@ -23845,6 +23939,7 @@ class Parser {
|
||||
request.onComplete(headers)
|
||||
|
||||
client[kQueue][client[kRunningIdx]++] = null
|
||||
socket[kSocketUsed] = true
|
||||
|
||||
if (socket[kWriting]) {
|
||||
assert(client[kRunning] === 0)
|
||||
@@ -23903,6 +23998,9 @@ async function connectH1 (client, socket) {
|
||||
socket[kWriting] = false
|
||||
socket[kReset] = false
|
||||
socket[kBlocking] = false
|
||||
socket[kIdleSocketValidation] = 0
|
||||
socket[kIdleSocketValidationTimeout] = null
|
||||
socket[kSocketUsed] = false
|
||||
socket[kParser] = new Parser(client, socket, llhttpInstance)
|
||||
|
||||
addListener(socket, 'error', function (err) {
|
||||
@@ -23913,8 +24011,11 @@ async function connectH1 (client, socket) {
|
||||
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
|
||||
// to the user.
|
||||
if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
|
||||
// We treat all incoming data so for as a valid response.
|
||||
parser.onMessageComplete()
|
||||
const parserErr = parser.finish()
|
||||
if (parserErr) {
|
||||
this[kError] = parserErr
|
||||
this[kClient][kOnError](parserErr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -23933,8 +24034,10 @@ async function connectH1 (client, socket) {
|
||||
const parser = this[kParser]
|
||||
|
||||
if (parser.statusCode && !parser.shouldKeepAlive) {
|
||||
// We treat all incoming data so far as a valid response.
|
||||
parser.onMessageComplete()
|
||||
const parserErr = parser.finish()
|
||||
if (parserErr) {
|
||||
util.destroy(this, parserErr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -23944,10 +24047,11 @@ async function connectH1 (client, socket) {
|
||||
const client = this[kClient]
|
||||
const parser = this[kParser]
|
||||
|
||||
clearIdleSocketValidation(this)
|
||||
|
||||
if (parser) {
|
||||
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
|
||||
// We treat all incoming data so far as a valid response.
|
||||
parser.onMessageComplete()
|
||||
this[kError] = parser.finish() || this[kError]
|
||||
}
|
||||
|
||||
this[kParser].destroy()
|
||||
@@ -24010,7 +24114,7 @@ async function connectH1 (client, socket) {
|
||||
return socket.destroyed
|
||||
},
|
||||
busy (request) {
|
||||
if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
|
||||
if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -24048,6 +24152,31 @@ async function connectH1 (client, socket) {
|
||||
}
|
||||
}
|
||||
|
||||
function clearIdleSocketValidation (socket) {
|
||||
if (socket[kIdleSocketValidationTimeout]) {
|
||||
clearTimeout(socket[kIdleSocketValidationTimeout])
|
||||
socket[kIdleSocketValidationTimeout] = null
|
||||
}
|
||||
|
||||
socket[kIdleSocketValidation] = 0
|
||||
}
|
||||
|
||||
function scheduleIdleSocketValidation (client, socket) {
|
||||
socket[kIdleSocketValidation] = 1
|
||||
socket[kIdleSocketValidationTimeout] = setTimeout(() => {
|
||||
socket[kIdleSocketValidationTimeout] = null
|
||||
socket[kIdleSocketValidation] = 2
|
||||
|
||||
if (client[kSocket] === socket && !socket.destroyed) {
|
||||
client[kResume]()
|
||||
}
|
||||
}, 0)
|
||||
socket[kIdleSocketValidationTimeout].unref?.()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./client.js')} client
|
||||
*/
|
||||
function resumeH1 (client) {
|
||||
const socket = client[kSocket]
|
||||
|
||||
@@ -24062,6 +24191,32 @@ function resumeH1 (client) {
|
||||
socket[kNoRef] = false
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
|
||||
if (socket[kIdleSocketValidation] === 0) {
|
||||
scheduleIdleSocketValidation(client, socket)
|
||||
socket[kParser].readMore()
|
||||
if (socket.destroyed) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (socket[kIdleSocketValidation] === 1) {
|
||||
socket[kParser].readMore()
|
||||
if (socket.destroyed) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0) {
|
||||
socket[kParser].readMore()
|
||||
if (socket.destroyed) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (client[kSize] === 0) {
|
||||
if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
|
||||
socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE)
|
||||
@@ -24155,6 +24310,7 @@ function writeH1 (client, request) {
|
||||
}
|
||||
|
||||
const socket = client[kSocket]
|
||||
clearIdleSocketValidation(socket)
|
||||
|
||||
const abort = (err) => {
|
||||
if (request.aborted || request.completed) {
|
||||
@@ -25476,9 +25632,10 @@ class Client extends DispatcherBase {
|
||||
autoSelectFamilyAttemptTimeout,
|
||||
// h2
|
||||
maxConcurrentStreams,
|
||||
allowH2
|
||||
allowH2,
|
||||
webSocket
|
||||
} = {}) {
|
||||
super()
|
||||
super({ webSocket })
|
||||
|
||||
if (keepAlive !== undefined) {
|
||||
throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
|
||||
@@ -26011,15 +26168,24 @@ const { kDestroy, kClose, kClosed, kDestroyed, kDispatch, kInterceptors } = __nc
|
||||
const kOnDestroyed = Symbol('onDestroyed')
|
||||
const kOnClosed = Symbol('onClosed')
|
||||
const kInterceptedDispatch = Symbol('Intercepted Dispatch')
|
||||
const kWebSocketOptions = Symbol('webSocketOptions')
|
||||
|
||||
class DispatcherBase extends Dispatcher {
|
||||
constructor () {
|
||||
constructor (opts) {
|
||||
super()
|
||||
|
||||
this[kDestroyed] = false
|
||||
this[kOnDestroyed] = null
|
||||
this[kClosed] = false
|
||||
this[kOnClosed] = []
|
||||
this[kWebSocketOptions] = opts?.webSocket ?? {}
|
||||
}
|
||||
|
||||
get webSocketOptions () {
|
||||
return {
|
||||
maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
|
||||
maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
|
||||
}
|
||||
}
|
||||
|
||||
get destroyed () {
|
||||
@@ -26583,8 +26749,8 @@ const kRemoveClient = Symbol('remove client')
|
||||
const kStats = Symbol('stats')
|
||||
|
||||
class PoolBase extends DispatcherBase {
|
||||
constructor () {
|
||||
super()
|
||||
constructor (opts) {
|
||||
super(opts)
|
||||
|
||||
this[kQueue] = new FixedQueue()
|
||||
this[kClients] = []
|
||||
@@ -26844,8 +27010,6 @@ class Pool extends PoolBase {
|
||||
allowH2,
|
||||
...options
|
||||
} = {}) {
|
||||
super()
|
||||
|
||||
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
|
||||
throw new InvalidArgumentError('invalid connections')
|
||||
}
|
||||
@@ -26870,6 +27034,8 @@ class Pool extends PoolBase {
|
||||
})
|
||||
}
|
||||
|
||||
super(options)
|
||||
|
||||
this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool)
|
||||
? options.interceptors.Pool
|
||||
: []
|
||||
@@ -31954,32 +32120,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
// If the attribute-name case-insensitively matches the string
|
||||
// "SameSite", the user agent MUST process the cookie-av as follows:
|
||||
|
||||
// 1. Let enforcement be "Default".
|
||||
let enforcement = 'Default'
|
||||
|
||||
const attributeValueLowercase = attributeValue.toLowerCase()
|
||||
// 2. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "None", set enforcement to "None".
|
||||
if (attributeValueLowercase.includes('none')) {
|
||||
enforcement = 'None'
|
||||
}
|
||||
|
||||
// 3. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "Strict", set enforcement to "Strict".
|
||||
if (attributeValueLowercase.includes('strict')) {
|
||||
enforcement = 'Strict'
|
||||
// 1. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "None", append an attribute to the cookie-attribute-list with an
|
||||
// attribute-name of "SameSite" and an attribute-value of "None".
|
||||
if (attributeValueLowercase === 'none') {
|
||||
cookieAttributeList.sameSite = 'None'
|
||||
} else if (attributeValueLowercase === 'strict') {
|
||||
// 2. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "Strict", append an attribute to the cookie-attribute-list with
|
||||
// an attribute-name of "SameSite" and an attribute-value of
|
||||
// "Strict".
|
||||
cookieAttributeList.sameSite = 'Strict'
|
||||
} else if (attributeValueLowercase === 'lax') {
|
||||
// 3. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "Lax", append an attribute to the cookie-attribute-list with an
|
||||
// attribute-name of "SameSite" and an attribute-value of "Lax".
|
||||
cookieAttributeList.sameSite = 'Lax'
|
||||
}
|
||||
|
||||
// 4. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "Lax", set enforcement to "Lax".
|
||||
if (attributeValueLowercase.includes('lax')) {
|
||||
enforcement = 'Lax'
|
||||
}
|
||||
|
||||
// 5. Append an attribute to the cookie-attribute-list with an
|
||||
// attribute-name of "SameSite" and an attribute-value of
|
||||
// enforcement.
|
||||
cookieAttributeList.sameSite = enforcement
|
||||
} else {
|
||||
cookieAttributeList.unparsed ??= []
|
||||
|
||||
@@ -44685,40 +44844,35 @@ const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
|
||||
const kBuffer = Symbol('kBuffer')
|
||||
const kLength = Symbol('kLength')
|
||||
|
||||
// Default maximum decompressed message size: 4 MB
|
||||
const kDefaultMaxDecompressedSize = 4 * 1024 * 1024
|
||||
|
||||
class PerMessageDeflate {
|
||||
/** @type {import('node:zlib').InflateRaw} */
|
||||
#inflate
|
||||
|
||||
#options = {}
|
||||
|
||||
/** @type {boolean} */
|
||||
#aborted = false
|
||||
|
||||
/** @type {Function|null} */
|
||||
#currentCallback = null
|
||||
#maxPayloadSize = 0
|
||||
|
||||
/**
|
||||
* @param {Map<string, string>} extensions
|
||||
*/
|
||||
constructor (extensions) {
|
||||
constructor (extensions, options) {
|
||||
this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
|
||||
this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
|
||||
|
||||
this.#maxPayloadSize = options.maxPayloadSize
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress a compressed payload.
|
||||
* @param {Buffer} chunk Compressed data
|
||||
* @param {boolean} fin Final fragment flag
|
||||
* @param {Function} callback Callback function
|
||||
*/
|
||||
decompress (chunk, fin, callback) {
|
||||
// An endpoint uses the following algorithm to decompress a message.
|
||||
// 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the
|
||||
// payload of the message.
|
||||
// 2. Decompress the resulting data using DEFLATE.
|
||||
|
||||
if (this.#aborted) {
|
||||
callback(new MessageSizeExceededError())
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.#inflate) {
|
||||
let windowBits = Z_DEFAULT_WINDOWBITS
|
||||
|
||||
@@ -44741,23 +44895,12 @@ class PerMessageDeflate {
|
||||
this.#inflate[kLength] = 0
|
||||
|
||||
this.#inflate.on('data', (data) => {
|
||||
if (this.#aborted) {
|
||||
return
|
||||
}
|
||||
|
||||
this.#inflate[kLength] += data.length
|
||||
|
||||
if (this.#inflate[kLength] > kDefaultMaxDecompressedSize) {
|
||||
this.#aborted = true
|
||||
if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) {
|
||||
callback(new MessageSizeExceededError())
|
||||
this.#inflate.removeAllListeners()
|
||||
this.#inflate.destroy()
|
||||
this.#inflate = null
|
||||
|
||||
if (this.#currentCallback) {
|
||||
const cb = this.#currentCallback
|
||||
this.#currentCallback = null
|
||||
cb(new MessageSizeExceededError())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -44770,14 +44913,13 @@ class PerMessageDeflate {
|
||||
})
|
||||
}
|
||||
|
||||
this.#currentCallback = callback
|
||||
this.#inflate.write(chunk)
|
||||
if (fin) {
|
||||
this.#inflate.write(tail)
|
||||
}
|
||||
|
||||
this.#inflate.flush(() => {
|
||||
if (this.#aborted || !this.#inflate) {
|
||||
if (!this.#inflate) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -44785,7 +44927,6 @@ class PerMessageDeflate {
|
||||
|
||||
this.#inflate[kBuffer].length = 0
|
||||
this.#inflate[kLength] = 0
|
||||
this.#currentCallback = null
|
||||
|
||||
callback(null, full)
|
||||
})
|
||||
@@ -44821,6 +44962,12 @@ const {
|
||||
const { WebsocketFrameSend } = __nccwpck_require__(3264)
|
||||
const { closeWebSocketConnection } = __nccwpck_require__(86897)
|
||||
const { PerMessageDeflate } = __nccwpck_require__(19469)
|
||||
const { MessageSizeExceededError } = __nccwpck_require__(68707)
|
||||
|
||||
function failWebsocketConnectionWithCode (ws, code, reason) {
|
||||
closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason))
|
||||
failWebsocketConnection(ws, reason)
|
||||
}
|
||||
|
||||
// This code was influenced by ws released under the MIT license.
|
||||
// Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
|
||||
@@ -44829,6 +44976,7 @@ const { PerMessageDeflate } = __nccwpck_require__(19469)
|
||||
|
||||
class ByteParser extends Writable {
|
||||
#buffers = []
|
||||
#fragmentsBytes = 0
|
||||
#byteOffset = 0
|
||||
#loop = false
|
||||
|
||||
@@ -44840,18 +44988,27 @@ class ByteParser extends Writable {
|
||||
/** @type {Map<string, PerMessageDeflate>} */
|
||||
#extensions
|
||||
|
||||
/** @type {number} */
|
||||
#maxFragments
|
||||
|
||||
/** @type {number} */
|
||||
#maxPayloadSize
|
||||
|
||||
/**
|
||||
* @param {import('./websocket').WebSocket} ws
|
||||
* @param {Map<string, string>|null} extensions
|
||||
* @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
|
||||
*/
|
||||
constructor (ws, extensions) {
|
||||
constructor (ws, extensions, options = {}) {
|
||||
super()
|
||||
|
||||
this.ws = ws
|
||||
this.#extensions = extensions == null ? new Map() : extensions
|
||||
this.#maxFragments = options.maxFragments ?? 0
|
||||
this.#maxPayloadSize = options.maxPayloadSize ?? 0
|
||||
|
||||
if (this.#extensions.has('permessage-deflate')) {
|
||||
this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions))
|
||||
this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions, options))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44867,6 +45024,19 @@ class ByteParser extends Writable {
|
||||
this.run(callback)
|
||||
}
|
||||
|
||||
#validatePayloadLength () {
|
||||
if (
|
||||
this.#maxPayloadSize > 0 &&
|
||||
!isControlFrame(this.#info.opcode) &&
|
||||
this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize
|
||||
) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1009, 'Payload size exceeds maximum allowed size')
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs whenever a new chunk is received.
|
||||
* Callback is called whenever there are no more chunks buffering,
|
||||
@@ -44955,6 +45125,10 @@ class ByteParser extends Writable {
|
||||
if (payloadLength <= 125) {
|
||||
this.#info.payloadLength = payloadLength
|
||||
this.#state = parserStates.READ_DATA
|
||||
|
||||
if (!this.#validatePayloadLength()) {
|
||||
return
|
||||
}
|
||||
} else if (payloadLength === 126) {
|
||||
this.#state = parserStates.PAYLOADLENGTH_16
|
||||
} else if (payloadLength === 127) {
|
||||
@@ -44979,6 +45153,10 @@ class ByteParser extends Writable {
|
||||
|
||||
this.#info.payloadLength = buffer.readUInt16BE(0)
|
||||
this.#state = parserStates.READ_DATA
|
||||
|
||||
if (!this.#validatePayloadLength()) {
|
||||
return
|
||||
}
|
||||
} else if (this.#state === parserStates.PAYLOADLENGTH_64) {
|
||||
if (this.#byteOffset < 8) {
|
||||
return callback()
|
||||
@@ -45001,6 +45179,10 @@ class ByteParser extends Writable {
|
||||
|
||||
this.#info.payloadLength = lower
|
||||
this.#state = parserStates.READ_DATA
|
||||
|
||||
if (!this.#validatePayloadLength()) {
|
||||
return
|
||||
}
|
||||
} else if (this.#state === parserStates.READ_DATA) {
|
||||
if (this.#byteOffset < this.#info.payloadLength) {
|
||||
return callback()
|
||||
@@ -45013,42 +45195,58 @@ class ByteParser extends Writable {
|
||||
this.#state = parserStates.INFO
|
||||
} else {
|
||||
if (!this.#info.compressed) {
|
||||
this.#fragments.push(body)
|
||||
if (!this.writeFragments(body)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
|
||||
return
|
||||
}
|
||||
|
||||
// If the frame is not fragmented, a message has been received.
|
||||
// If the frame is fragmented, it will terminate with a fin bit set
|
||||
// and an opcode of 0 (continuation), therefore we handle that when
|
||||
// parsing continuation frames, not here.
|
||||
if (!this.#info.fragmented && this.#info.fin) {
|
||||
const fullMessage = Buffer.concat(this.#fragments)
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, fullMessage)
|
||||
this.#fragments.length = 0
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments())
|
||||
}
|
||||
|
||||
this.#state = parserStates.INFO
|
||||
} else {
|
||||
this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
|
||||
if (error) {
|
||||
failWebsocketConnection(this.ws, error.message)
|
||||
return
|
||||
}
|
||||
this.#extensions.get('permessage-deflate').decompress(
|
||||
body,
|
||||
this.#info.fin,
|
||||
(error, data) => {
|
||||
if (error) {
|
||||
const code = error instanceof MessageSizeExceededError ? 1009 : 1007
|
||||
failWebsocketConnectionWithCode(this.ws, code, error.message)
|
||||
return
|
||||
}
|
||||
|
||||
this.#fragments.push(data)
|
||||
if (!this.writeFragments(data)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.#info.fin) {
|
||||
this.#state = parserStates.INFO
|
||||
this.#loop = true
|
||||
this.run(callback)
|
||||
return
|
||||
}
|
||||
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments())
|
||||
|
||||
if (!this.#info.fin) {
|
||||
this.#state = parserStates.INFO
|
||||
this.#loop = true
|
||||
this.#state = parserStates.INFO
|
||||
this.run(callback)
|
||||
return
|
||||
}
|
||||
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, Buffer.concat(this.#fragments))
|
||||
|
||||
this.#loop = true
|
||||
this.#state = parserStates.INFO
|
||||
this.#fragments.length = 0
|
||||
this.run(callback)
|
||||
})
|
||||
)
|
||||
|
||||
this.#loop = false
|
||||
break
|
||||
@@ -45100,6 +45298,35 @@ class ByteParser extends Writable {
|
||||
return buffer
|
||||
}
|
||||
|
||||
writeFragments (fragment) {
|
||||
if (
|
||||
this.#maxFragments > 0 &&
|
||||
this.#fragments.length === this.#maxFragments
|
||||
) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1008, 'Too many message fragments')
|
||||
return false
|
||||
}
|
||||
|
||||
this.#fragmentsBytes += fragment.length
|
||||
this.#fragments.push(fragment)
|
||||
return true
|
||||
}
|
||||
|
||||
consumeFragments () {
|
||||
const fragments = this.#fragments
|
||||
|
||||
if (fragments.length === 1) {
|
||||
this.#fragmentsBytes = 0
|
||||
return fragments.shift()
|
||||
}
|
||||
|
||||
const output = Buffer.concat(fragments, this.#fragmentsBytes)
|
||||
this.#fragments = []
|
||||
this.#fragmentsBytes = 0
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
parseCloseBody (data) {
|
||||
assert(data.length !== 1)
|
||||
|
||||
@@ -46135,7 +46362,14 @@ class WebSocket extends EventTarget {
|
||||
// once this happens, the connection is open
|
||||
this[kResponse] = response
|
||||
|
||||
const parser = new ByteParser(this, parsedExtensions)
|
||||
const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions
|
||||
const maxFragments = webSocketOptions?.maxFragments
|
||||
const maxPayloadSize = webSocketOptions?.maxPayloadSize
|
||||
|
||||
const parser = new ByteParser(this, parsedExtensions, {
|
||||
maxFragments,
|
||||
maxPayloadSize
|
||||
})
|
||||
parser.on('drain', onParserDrain)
|
||||
parser.on('error', onParserError.bind(this))
|
||||
|
||||
@@ -46379,7 +46613,11 @@ const cachePackages = async (packageManager) => {
|
||||
return;
|
||||
}
|
||||
const cacheId = await cache.saveCache(cachePaths, primaryKey);
|
||||
if (cacheId == -1) {
|
||||
if (cacheId === -1) {
|
||||
// saveCache returns -1 without throwing when the cache was not saved, e.g.
|
||||
// a reserve collision or a read-only token (fork PR). @actions/cache has
|
||||
// already logged the reason at the appropriate severity, so just trace it.
|
||||
core.debug(`Cache was not saved for the key: ${primaryKey}`);
|
||||
return;
|
||||
}
|
||||
core.info(`Cache saved with the key: ${primaryKey}`);
|
||||
@@ -88247,7 +88485,7 @@ function randomUUID() {
|
||||
/***/ 50591:
|
||||
/***/ ((module) => {
|
||||
|
||||
(()=>{"use strict";var t={d:(e,n)=>{for(var i in n)t.o(n,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:n[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{XMLBuilder:()=>It,XMLParser:()=>xt,XMLValidator:()=>jt});const n=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",i=new RegExp("^["+n+"]["+n+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function s(t,e){const n=[];let i=e.exec(t);for(;i;){const s=[];s.startIndex=e.lastIndex-i[0].length;const r=i.length;for(let t=0;t<r;t++)s.push(i[t]);n.push(s),i=e.exec(t)}return n}const r=function(t){return!(null==i.exec(t))},o=["hasOwnProperty","toString","valueOf","__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__"],a=["__proto__","constructor","prototype"],h={allowBooleanAttributes:!1,unpairedTags:[]};function l(t,e){e=Object.assign({},h,e);const n=[];let i=!1,s=!1;"\ufeff"===t[0]&&(t=t.substr(1));for(let r=0;r<t.length;r++)if("<"===t[r]&&"?"===t[r+1]){if(r+=2,r=p(t,r),r.err)return r}else{if("<"!==t[r]){if(u(t[r]))continue;return N("InvalidChar","char '"+t[r]+"' is not expected.",w(t,r))}{let o=r;if(r++,"!"===t[r]){r=c(t,r);continue}{let a=!1;"/"===t[r]&&(a=!0,r++);let h="";for(;r<t.length&&">"!==t[r]&&" "!==t[r]&&"\t"!==t[r]&&"\n"!==t[r]&&"\r"!==t[r];r++)h+=t[r];if(h=h.trim(),"/"===h[h.length-1]&&(h=h.substring(0,h.length-1),r--),!E(h)){let e;return e=0===h.trim().length?"Invalid space after '<'.":"Tag '"+h+"' is an invalid name.",N("InvalidTag",e,w(t,r))}const l=g(t,r);if(!1===l)return N("InvalidAttr","Attributes for '"+h+"' have open quote.",w(t,r));let d=l.value;if(r=l.index,"/"===d[d.length-1]){const n=r-d.length;d=d.substring(0,d.length-1);const s=x(d,e);if(!0!==s)return N(s.err.code,s.err.msg,w(t,n+s.err.line));i=!0}else if(a){if(!l.tagClosed)return N("InvalidTag","Closing tag '"+h+"' doesn't have proper closing.",w(t,r));if(d.trim().length>0)return N("InvalidTag","Closing tag '"+h+"' can't have attributes or invalid starting.",w(t,o));if(0===n.length)return N("InvalidTag","Closing tag '"+h+"' has not been opened.",w(t,o));{const e=n.pop();if(h!==e.tagName){let n=w(t,e.tagStartPos);return N("InvalidTag","Expected closing tag '"+e.tagName+"' (opened in line "+n.line+", col "+n.col+") instead of closing tag '"+h+"'.",w(t,o))}0==n.length&&(s=!0)}}else{const a=x(d,e);if(!0!==a)return N(a.err.code,a.err.msg,w(t,r-d.length+a.err.line));if(!0===s)return N("InvalidXml","Multiple possible root nodes found.",w(t,r));-1!==e.unpairedTags.indexOf(h)||n.push({tagName:h,tagStartPos:o}),i=!0}for(r++;r<t.length;r++)if("<"===t[r]){if("!"===t[r+1]){r++,r=c(t,r);continue}if("?"!==t[r+1])break;if(r=p(t,++r),r.err)return r}else if("&"===t[r]){const e=b(t,r);if(-1==e)return N("InvalidChar","char '&' is not expected.",w(t,r));r=e}else if(!0===s&&!u(t[r]))return N("InvalidXml","Extra text at the end",w(t,r));"<"===t[r]&&r--}}}return i?1==n.length?N("InvalidTag","Unclosed tag '"+n[0].tagName+"'.",w(t,n[0].tagStartPos)):!(n.length>0)||N("InvalidXml","Invalid '"+JSON.stringify(n.map(t=>t.tagName),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):N("InvalidXml","Start tag expected.",1)}function u(t){return" "===t||"\t"===t||"\n"===t||"\r"===t}function p(t,e){const n=e;for(;e<t.length;e++)if("?"==t[e]||" "==t[e]){const i=t.substr(n,e-n);if(e>5&&"xml"===i)return N("InvalidXml","XML declaration allowed only at the start of the document.",w(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}continue}return e}function c(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e<t.length;e++)if("-"===t[e]&&"-"===t[e+1]&&">"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){let n=1;for(e+=8;e<t.length;e++)if("<"===t[e])n++;else if(">"===t[e]&&(n--,0===n))break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e<t.length;e++)if("]"===t[e]&&"]"===t[e+1]&&">"===t[e+2]){e+=2;break}return e}const d='"',f="'";function g(t,e){let n="",i="",s=!1;for(;e<t.length;e++){if(t[e]===d||t[e]===f)""===i?i=t[e]:i!==t[e]||(i="");else if(">"===t[e]&&""===i){s=!0;break}n+=t[e]}return""===i&&{value:n,index:e,tagClosed:s}}const m=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function x(t,e){const n=s(t,m),i={};for(let t=0;t<n.length;t++){if(0===n[t][1].length)return N("InvalidAttr","Attribute '"+n[t][2]+"' has no space in starting.",S(n[t]));if(void 0!==n[t][3]&&void 0===n[t][4])return N("InvalidAttr","Attribute '"+n[t][2]+"' is without value.",S(n[t]));if(void 0===n[t][3]&&!e.allowBooleanAttributes)return N("InvalidAttr","boolean attribute '"+n[t][2]+"' is not allowedLine truncated
|
||||
(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{XMLBuilder:()=>xe,XMLParser:()=>Jt,XMLValidator:()=>be});const i=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",n=new RegExp("^["+i+"]["+i+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function r(t,e){const i=[];let n=e.exec(t);for(;n;){const r=[];r.startIndex=e.lastIndex-n[0].length;const s=n.length;for(let t=0;t<s;t++)r.push(n[t]);i.push(r),n=e.exec(t)}return i}const s=function(t){return!(null==n.exec(t))},o=["hasOwnProperty","toString","valueOf","__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__"],a=["__proto__","constructor","prototype"],l={allowBooleanAttributes:!1,unpairedTags:[]};function p(t,e){e=Object.assign({},l,e);const i=[];let n=!1,r=!1;"\ufeff"===t[0]&&(t=t.substr(1));for(let s=0;s<t.length;s++)if("<"===t[s]&&"?"===t[s+1]){if(s+=2,s=h(t,s),s.err)return s}else{if("<"!==t[s]){if(c(t[s]))continue;return y("InvalidChar","char '"+t[s]+"' is not expected.",w(t,s))}{let o=s;if(s++,"!"===t[s]){s=d(t,s);continue}{let a=!1;"/"===t[s]&&(a=!0,s++);let l="";for(;s<t.length&&">"!==t[s]&&" "!==t[s]&&"\t"!==t[s]&&"\n"!==t[s]&&"\r"!==t[s];s++)l+=t[s];if(l=l.trim(),"/"===l[l.length-1]&&(l=l.substring(0,l.length-1),s--),!E(l)){let e;return e=0===l.trim().length?"Invalid space after '<'.":"Tag '"+l+"' is an invalid name.",y("InvalidTag",e,w(t,s))}const p=g(t,s);if(!1===p)return y("InvalidAttr","Attributes for '"+l+"' have open quote.",w(t,s));let u=p.value;if(s=p.index,"/"===u[u.length-1]){const i=s-u.length;u=u.substring(0,u.length-1);const r=x(u,e);if(!0!==r)return y(r.err.code,r.err.msg,w(t,i+r.err.line));n=!0}else if(a){if(!p.tagClosed)return y("InvalidTag","Closing tag '"+l+"' doesn't have proper closing.",w(t,s));if(u.trim().length>0)return y("InvalidTag","Closing tag '"+l+"' can't have attributes or invalid starting.",w(t,o));if(0===i.length)return y("InvalidTag","Closing tag '"+l+"' has not been opened.",w(t,o));{const e=i.pop();if(l!==e.tagName){let i=w(t,e.tagStartPos);return y("InvalidTag","Expected closing tag '"+e.tagName+"' (opened in line "+i.line+", col "+i.col+") instead of closing tag '"+l+"'.",w(t,o))}0==i.length&&(r=!0)}}else{const a=x(u,e);if(!0!==a)return y(a.err.code,a.err.msg,w(t,s-u.length+a.err.line));if(!0===r)return y("InvalidXml","Multiple possible root nodes found.",w(t,s));-1!==e.unpairedTags.indexOf(l)||i.push({tagName:l,tagStartPos:o}),n=!0}for(s++;s<t.length;s++)if("<"===t[s]){if("!"===t[s+1]){s++,s=d(t,s);continue}if("?"!==t[s+1])break;if(s=h(t,++s),s.err)return s}else if("&"===t[s]){const e=b(t,s);if(-1==e)return y("InvalidChar","char '&' is not expected.",w(t,s));s=e}else if(!0===r&&!c(t[s]))return y("InvalidXml","Extra text at the end",w(t,s));"<"===t[s]&&s--}}}return n?1==i.length?y("InvalidTag","Unclosed tag '"+i[0].tagName+"'.",w(t,i[0].tagStartPos)):!(i.length>0)||y("InvalidXml","Invalid '"+JSON.stringify(i.map(t=>t.tagName),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):y("InvalidXml","Start tag expected.",1)}function c(t){return" "===t||"\t"===t||"\n"===t||"\r"===t}function h(t,e){const i=e;for(;e<t.length;e++)if("?"==t[e]||" "==t[e]){const n=t.substr(i,e-i);if(e>5&&"xml"===n)return y("InvalidXml","XML declaration allowed only at the start of the document.",w(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}continue}return e}function d(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e<t.length;e++)if("-"===t[e]&&"-"===t[e+1]&&">"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){let i=1;for(e+=8;e<t.length;e++)if("<"===t[e])i++;else if(">"===t[e]&&(i--,0===i))break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e<t.length;e++)if("]"===t[e]&&"]"===t[e+1]&&">"===t[e+2]){e+=2;break}return e}const u='"',f="'";function g(t,e){let i="",n="",r=!1;for(;e<t.length;e++){if(t[e]===u||t[e]===f)""===n?n=t[e]:n!==t[e]||(n="");else if(">"===t[e]&&""===n){r=!0;break}i+=t[e]}return""===n&&{value:i,index:e,tagClosed:r}}const m=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function x(t,e){const i=r(t,m),n={};for(let t=0;t<i.length;t++){if(0===i[t][1].length)return y("InvalidAttr","Attribute '"+i[t][2]+"' has no space in starting.",v(i[t]));if(void 0!==i[t][3]&&void 0===i[t][4])return y("InvalidAttr","Attribute '"+i[t][2]+"' is without value.",v(i[t]));if(void 0===i[t][3]&&!e.allowBooleanAttributes)return y("InvalidAttr","boolean attribute '"+i[t][2]+"' is not allowedLine truncated
|
||||
|
||||
/***/ }),
|
||||
|
||||
@@ -88255,7 +88493,7 @@ function randomUUID() {
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.0.5","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","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"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.1.0","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","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"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
Vendored
+815
-24445
File diff suppressed because it is too large.
Load diff
+102
-26
@@ -69,6 +69,7 @@ steps:
|
||||
with:
|
||||
node-version: '24'
|
||||
check-latest: true
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -86,6 +87,7 @@ steps:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -131,6 +133,7 @@ jobs:
|
||||
with:
|
||||
node-version: '24'
|
||||
architecture: 'x64' # optional, x64 or x86. If not specified, x64 will be used by default
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -151,6 +154,7 @@ jobs:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24.0.0-v8-canary' # it will install the latest v8 canary release for node 24.0.0
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -166,6 +170,7 @@ jobs:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24-v8-canary' # it will install the latest v8 canary release for node 24
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -182,6 +187,7 @@ jobs:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 'v24.0.0-v8-canary2025030537242e55ac'
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -202,6 +208,7 @@ jobs:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24-nightly' # it will install the latest nightly release for node 24
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -218,6 +225,7 @@ jobs:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24.0.0-nightly' # it will install the latest nightly release for node 24.0.0
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -234,6 +242,7 @@ jobs:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24.0.0-nightly202505066102159fa1'
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -252,11 +261,12 @@ jobs:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24.0.0-rc.4'
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
**Note:** Unlike nightly versions, which support version range specifiers, you must specify the exact version for a release candidate: `24.0.0-rc.4`.
|
||||
**Note**: Unlike nightly versions, which support version range specifiers, you must specify the exact version for a release candidate: `24.0.0-rc.4`.
|
||||
|
||||
## Caching packages data
|
||||
The action follows [actions/cache](https://github.com/actions/cache/blob/main/examples.md#node---npm) guidelines, and caches global cache on the machine instead of `node_modules`, so cache can be reused between different Node.js versions.
|
||||
@@ -329,36 +339,52 @@ steps:
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
**Restore-Only Cache**
|
||||
**Restore-only cache**
|
||||
|
||||
You can restore caches without saving new entries, which helps reduce cache writes and storage usage in read-only cache workflows.
|
||||
|
||||
```yaml
|
||||
## In some workflows, you may want to restore a cache without saving it. This can help reduce cache writes and storage usage in workflows that only need to read from cache
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# Restore Node.js modules cache (restore-only)
|
||||
- name: Restore Node modules cache
|
||||
uses: actions/cache@v5
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
# Setup Node.js
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
# Install dependencies
|
||||
- run: npm install
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# - uses: pnpm/action-setup@v6
|
||||
# with:
|
||||
# version: 10
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
|
||||
- name: Normalize runner architecture
|
||||
shell: bash
|
||||
run: echo "ARCH=$(echo '${{ runner.arch }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
|
||||
|
||||
- name: Output of cache path
|
||||
id: cachepath
|
||||
shell: bash
|
||||
run: echo "path=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||
# run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
||||
# For yarn workflow, output of yarn cache dir (v1) or yarn config get cacheFolder (v2+)
|
||||
# run: echo "path=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore Node cache
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ${{ steps.cachepath.outputs.path }}
|
||||
key: node-cache-${{ runner.os }}-${{ env.ARCH }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
# key: node-cache-${{ runner.os }}-${{ env.ARCH }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
# key: node-cache-${{ runner.os }}-${{ env.ARCH }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- run: npm ci
|
||||
# - run: yarn install --frozen-lockfile # optional, --immutable
|
||||
# - run: pnpm install
|
||||
```
|
||||
> **Note**: Uncomment the commands relevant to your project's package manager.
|
||||
|
||||
> For more details related to cache scenarios, please refer [Node – npm](https://github.com/actions/cache/blob/main/examples.md#node---npm).
|
||||
> For more details related to cache scenarios, please refer [actions/cache/restore](https://github.com/actions/cache/tree/main/restore#only-restore-cache).
|
||||
|
||||
## Multiple Operating Systems and Architectures
|
||||
## Multiple operating systems and architectures
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
@@ -389,6 +415,7 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
architecture: ${{ matrix.architecture }}
|
||||
package-manager-cache: false # Disable automatic npm caching if not required
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@@ -401,6 +428,7 @@ steps:
|
||||
with:
|
||||
node-version: '24.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
package-manager-cache: false # Disable automatic npm dependency caching to reduce cache poisoning risk
|
||||
- run: npm ci
|
||||
- run: npm publish
|
||||
env:
|
||||
@@ -408,6 +436,7 @@ steps:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
registry-url: 'https://npm.pkg.github.com'
|
||||
package-manager-cache: false # Disable automatic npm dependency caching to reduce cache poisoning risk
|
||||
- run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -421,6 +450,7 @@ steps:
|
||||
with:
|
||||
node-version: '24.x'
|
||||
registry-url: <registry url>
|
||||
package-manager-cache: false # Disable automatic npm dependency caching to reduce cache poisoning risk
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn publish
|
||||
env:
|
||||
@@ -428,6 +458,7 @@ steps:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
registry-url: 'https://npm.pkg.github.com'
|
||||
package-manager-cache: false # Disable automatic npm dependency caching to reduce cache poisoning risk
|
||||
- run: yarn publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -441,6 +472,7 @@ steps:
|
||||
with:
|
||||
node-version: '24.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
package-manager-cache: false # Disable automatic npm dependency caching to reduce cache poisoning risk
|
||||
# Skip post-install scripts here, as a malicious
|
||||
# script could steal NODE_AUTH_TOKEN.
|
||||
- run: npm ci --ignore-scripts
|
||||
@@ -460,6 +492,7 @@ steps:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24.x'
|
||||
package-manager-cache: false # Disable automatic npm dependency caching to reduce cache poisoning risk
|
||||
- name: Setup .yarnrc.yml
|
||||
run: |
|
||||
yarn config set npmScopes.my-org.npmRegistryServer "https://npm.pkg.github.com"
|
||||
@@ -475,6 +508,48 @@ To access private GitHub Packages within the same organization, go to "Manage Ac
|
||||
|
||||
Please refer to the [Ensuring workflow access to your package - Configuring a package's access control and visibility](https://docs.github.com/en/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-workflow-access-to-your-package) for more details.
|
||||
|
||||
## Publishing to npm with Trusted Publisher (OIDC)
|
||||
|
||||
npm supports Trusted Publishers, enabling packages to be published from GitHub Actions using OpenID Connect (OIDC) instead of long-lived npm tokens. This improves security by replacing static credentials with short-lived tokens, reducing the risk of credential leakage and simplifying authentication in CI/CD workflows.
|
||||
|
||||
### Requirements
|
||||
|
||||
Trusted publishing requires a compatible npm version:
|
||||
|
||||
* **npm ≥ 11.5.1 (required)**
|
||||
* **Node.js 24 or newer (recommended)** — includes a compatible npm version by default
|
||||
|
||||
> If npm is below 11.5.1, publishing will fail even if OIDC permissions are correctly configured.
|
||||
|
||||
You must also configure a **Trusted Publisher** in npm for your package/scope that matches your GitHub repository and workflow (and optional environment, if used).
|
||||
|
||||
> **Note**: In publishing workflows, set `package-manager-cache: false` because setup-node enables npm caching automatically when `package.json` specifies npm via `packageManager` or `devEngines.packageManager` (see [Running without a lockfile](#running-without-a-lockfile)), and a poisoned cache may expose credentials (including OIDC tokens) to attacker-controlled code.
|
||||
|
||||
### Example workflow
|
||||
|
||||
```yaml
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # Required for OIDC
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
package-manager-cache: false # Disable automatic npm dependency caching to reduce cache poisoning risk
|
||||
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm publish
|
||||
```
|
||||
|
||||
> **Note**: If the Trusted Publisher configuration (GitHub owner/repo/workflow file, and optional environment) does not match the workflow run identity exactly, publishing may fail with **E404 Not Found** even if the package exists on npm.
|
||||
|
||||
For more details, see the [npm Trusted Publishers documentation](https://docs.npmjs.com/trusted-publishers) and the [GitHub Actions OpenID Connect (OIDC) overview](https://docs.github.com/en/actions/concepts/security/openid-connect).
|
||||
|
||||
## Use private mirror
|
||||
|
||||
It is possible to use a private mirror hosting Node.js binaries. This mirror must be a full mirror of the official Node.js distribution.
|
||||
@@ -488,4 +563,5 @@ The token will be passed in the `Authorization` header.
|
||||
node-version: '24.x'
|
||||
mirror: 'https://nodejs.org/dist'
|
||||
mirror-token: 'your-mirror-token'
|
||||
cache-package-manager: false # Disable automatic npm caching if not required
|
||||
```
|
||||
@@ -0,0 +1,74 @@
|
||||
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||
import js from '@eslint/js';
|
||||
import tsParser from '@typescript-eslint/parser';
|
||||
import tsPlugin from '@typescript-eslint/eslint-plugin';
|
||||
import jest from 'eslint-plugin-jest';
|
||||
import n from 'eslint-plugin-n';
|
||||
import prettier from 'eslint-config-prettier';
|
||||
import globals from 'globals';
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: ['**/*', '!src/**', '!__tests__/**']
|
||||
},
|
||||
js.configs.recommended,
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
languageOptions: {
|
||||
parser: tsParser,
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.es2015
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
'@typescript-eslint': tsPlugin,
|
||||
n
|
||||
},
|
||||
rules: {
|
||||
...tsPlugin.configs.recommended.rules,
|
||||
'@typescript-eslint/no-require-imports': 'error',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': [
|
||||
'error',
|
||||
{
|
||||
'ts-ignore': 'allow-with-description'
|
||||
}
|
||||
],
|
||||
'no-console': 'error',
|
||||
yoda: 'error',
|
||||
'prefer-const': [
|
||||
'error',
|
||||
{
|
||||
destructuring: 'all'
|
||||
}
|
||||
],
|
||||
'no-control-regex': 'off',
|
||||
'no-constant-condition': ['error', {checkLoops: false}],
|
||||
'no-undef': 'off',
|
||||
'no-useless-assignment': 'off',
|
||||
'n/no-extraneous-import': 'error'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*{test,spec}.ts'],
|
||||
plugins: {jest},
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.jest
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
...jest.configs['flat/recommended'].rules,
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'jest/no-standalone-expect': 'off',
|
||||
'jest/no-conditional-expect': 'off',
|
||||
'no-console': 'off'
|
||||
}
|
||||
},
|
||||
prettier
|
||||
];
|
||||
Generated
+84
-47
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "setup-node",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "setup-node",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^5.0.5",
|
||||
"@actions/cache": "^5.1.0",
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/github": "^6.0.1",
|
||||
@@ -42,9 +42,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/cache": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.0.5.tgz",
|
||||
"integrity": "sha512-jiQSg0gfd+C2KPgcmdCOq7dCuCIQQWQ4b1YfGIRaaA9w7PJbRwTOcCz4LiFEUnqZGf0ha/8OKL3BeNwetHzYsQ==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.1.0.tgz",
|
||||
"integrity": "sha512-kTIj4YPrjjRPKSGlj7f8eq+Pijoy/SKBEbJcAwNsQTFGEF29NGqj1mqD02/PmhV6r4bRAixycexAWpmUJ2aCwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^2.0.0",
|
||||
@@ -112,18 +112,6 @@
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/github/node_modules/undici": {
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/glob": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.5.1.tgz",
|
||||
@@ -1047,15 +1035,6 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
|
||||
@@ -1553,6 +1532,18 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodable/entities": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz",
|
||||
"integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/nodable"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -2277,6 +2268,18 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/anynum": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz",
|
||||
"integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@@ -3320,9 +3323,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-xml-builder": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
|
||||
"integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
|
||||
"integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -3331,13 +3334,14 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-expression-matcher": "^1.1.3"
|
||||
"path-expression-matcher": "^1.5.0",
|
||||
"xml-naming": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-xml-parser": {
|
||||
"version": "5.5.11",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.11.tgz",
|
||||
"integrity": "sha512-QL0eb0YbSTVWF6tTf1+LEMSgtCEjBYPpnAjoLC8SscESlAjXEIRJ7cHtLG0pLeDFaZLa4VKZLArtA/60ZS7vyA==",
|
||||
"version": "5.9.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.9.2.tgz",
|
||||
"integrity": "sha512-DYPkXnVSJHAGAkSBeVYhEo/seIpz2SLr9OQcX7m6lXaX3gvoB+DCKzFdZIEhZGI3I1DUhObBAUOT/v2xfoXz/w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -3346,9 +3350,12 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-xml-builder": "^1.1.4",
|
||||
"path-expression-matcher": "^1.4.0",
|
||||
"strnum": "^2.2.3"
|
||||
"@nodable/entities": "^2.2.0",
|
||||
"fast-xml-builder": "^1.2.0",
|
||||
"is-unsafe": "^1.0.1",
|
||||
"path-expression-matcher": "^1.5.0",
|
||||
"strnum": "^2.4.0",
|
||||
"xml-naming": "^0.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"fxparser": "src/cli/cli.js"
|
||||
@@ -3863,6 +3870,18 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-unsafe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-unsafe/-/is-unsafe-1.0.1.tgz",
|
||||
"integrity": "sha512-CLK2+VdgERgD96EYm5lUQssZYlRg2tkZnbsxZoacmSiRxiFJ4Nk4SzjCl+Ur+v3kXIY9dTIdb3IH22y1mZ56LA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -4977,9 +4996,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/path-expression-matcher": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.4.0.tgz",
|
||||
"integrity": "sha512-s4DQMxIdhj3jLFWd9LxHOplj4p9yQ4ffMGowFf3cpEgrrJjEhN0V5nxw4Ye1EViAGDoL4/1AeO6qHpqYPOzE4Q==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
|
||||
"integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -5575,16 +5594,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/strnum": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz",
|
||||
"integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==",
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.1.tgz",
|
||||
"integrity": "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"anynum": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
@@ -5823,9 +5845,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||
"version": "6.27.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz",
|
||||
"integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
@@ -5981,6 +6003,21 @@
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xml-naming": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
|
||||
"integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
||||
+6
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "setup-node",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.0",
|
||||
"private": true,
|
||||
"description": "setup node action",
|
||||
"main": "lib/setup-node.js",
|
||||
@@ -28,7 +28,7 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^5.0.5",
|
||||
"@actions/cache": "^5.1.0",
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/github": "^6.0.1",
|
||||
@@ -55,5 +55,9 @@
|
||||
"prettier": "^3.6.2",
|
||||
"ts-jest": "^29.4.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"overrides": {
|
||||
"undici": "^6.24.1",
|
||||
"fast-xml-parser": "^5.9.2"
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -46,9 +46,8 @@ function writeRegistryToFile(registryUrl: string, fileLocation: string) {
|
||||
newContents += `${authString}${os.EOL}${registryString}`;
|
||||
fs.writeFileSync(fileLocation, newContents);
|
||||
core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation);
|
||||
// Export empty node_auth_token if didn't exist so npm doesn't complain about not being able to find it
|
||||
core.exportVariable(
|
||||
'NODE_AUTH_TOKEN',
|
||||
process.env.NODE_AUTH_TOKEN || 'XXXXX-XXXXX-XXXXX-XXXXX'
|
||||
);
|
||||
// Only export NODE_AUTH_TOKEN if explicitly provided by user
|
||||
if (Object.prototype.hasOwnProperty.call(process.env, 'NODE_AUTH_TOKEN')) {
|
||||
core.exportVariable('NODE_AUTH_TOKEN', process.env.NODE_AUTH_TOKEN);
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ export const restoreCache = async (
|
||||
core.debug(`primary key is ${primaryKey}`);
|
||||
|
||||
core.saveState(State.CachePrimaryKey, primaryKey);
|
||||
core.setOutput('cache-primary-key', primaryKey);
|
||||
|
||||
const isManagedByYarnBerry = await repoHasYarnBerryManagedDependencies(
|
||||
packageManagerInfo,
|
||||
@@ -61,6 +62,8 @@ export const restoreCache = async (
|
||||
}
|
||||
|
||||
core.setOutput('cache-hit', Boolean(cacheKey));
|
||||
core.setOutput('cache-matched-key', cacheKey);
|
||||
core.debug(`cache-matched-key is ${cacheKey}`);
|
||||
|
||||
if (!cacheKey) {
|
||||
core.info(`${packageManager} cache is not found`);
|
||||
|
||||
+5
-1
@@ -62,7 +62,11 @@ const cachePackages = async (packageManager: string) => {
|
||||
}
|
||||
|
||||
const cacheId = await cache.saveCache(cachePaths, primaryKey);
|
||||
if (cacheId == -1) {
|
||||
if (cacheId === -1) {
|
||||
// saveCache returns -1 without throwing when the cache was not saved, e.g.
|
||||
// a reserve collision or a read-only token (fork PR). @actions/cache has
|
||||
// already logged the reason at the appropriate severity, so just trace it.
|
||||
core.debug(`Cache was not saved for the key: ${primaryKey}`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,9 @@ export default class OfficialBuilds extends BaseDistribution {
|
||||
downloadPath = await tc.downloadTool(
|
||||
versionInfo.downloadUrl,
|
||||
undefined,
|
||||
this.nodeInfo.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth
|
||||
this.nodeInfo.mirror && this.nodeInfo.mirrorToken
|
||||
? this.nodeInfo.mirrorToken
|
||||
: this.nodeInfo.auth
|
||||
);
|
||||
|
||||
if (downloadPath) {
|
||||
@@ -188,7 +190,9 @@ export default class OfficialBuilds extends BaseDistribution {
|
||||
return tc.getManifestFromRepo(
|
||||
'actions',
|
||||
'node-versions',
|
||||
this.nodeInfo.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth,
|
||||
this.nodeInfo.mirror && this.nodeInfo.mirrorToken
|
||||
? this.nodeInfo.mirrorToken
|
||||
: this.nodeInfo.auth,
|
||||
'main'
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user