Compare commits

..

9 Commits

Author SHA1 Message Date
41dfa10bad Enhance workflows and Upgrade micromatch Dependency (#510)
* Update workflows and bump dependencies

* Add test for Go 1.22 and 1.23

* Update Go versions in local-cache setup and include macos-latest with ARM64 architecture
2024-10-23 22:39:31 -05:00
941977282c Revise isGhes logic (#511)
* Revise `isGhes` logic

* ran `npm run format`

* added unit test

* tweaked unit test

* ran `npm run format`
2024-10-21 11:56:08 -05:00
d60b41a563 Merge pull request #502 from actions/Jcambass-patch-1
Upgrade IA Publish
2024-09-26 08:24:19 +02:00
e09f57f6a9 Upgrade IA Publish 2024-09-16 17:20:25 +02:00
df1a11710e Merge pull request #500 from actions/Jcambass-patch-1
Add workflow file for publishing releases to immutable action package
2024-09-11 10:48:12 +02:00
49582f6476 Add workflow file for publishing releases to immutable action package
This workflow file publishes new action releases to the immutable action package of the same name as this repo.

This is part of the Immutable Actions project which is not yet fully released to the public. First party actions like this one are part of our initial testing of this feature.
2024-09-11 10:43:06 +02:00
b26d40294f fix: add arch to cache key (#493) 2024-08-26 15:19:57 -05:00
0a12ed9d6a Bump braces from 3.0.2 to 3.0.3 (#487)
* Bump braces from 3.0.2 to 3.0.3

Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

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

* Bump undici from 5.28.3 to 5.28.4

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: HarithaVattikuti <73516759+HarithaVattikuti@users.noreply.github.com>
2024-06-27 13:16:26 -05:00
4ab57d7ea2 Fix versions check failure (#479)
* Update to latest Go versions

* Updated versions

* Update test data

* Update test data
2024-05-10 11:25:20 -05:00
12 changed files with 644 additions and 125 deletions

View File

@ -0,0 +1,20 @@
name: 'Publish Immutable Action Version'
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
packages: write
steps:
- name: Checking out
uses: actions/checkout@v4
- name: Publish
id: publish
uses: actions/publish-immutable-action@0.0.3

View File

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

View File

@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
steps:
- uses: actions/checkout@v4
- name: Setup Go Stable
@ -33,7 +33,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
steps:
- uses: actions/checkout@v4
- name: Setup Go oldStable
@ -48,12 +48,14 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
version: [stable, oldstable]
architecture: [x64, x32]
exclude:
- os: macos-latest
architecture: x32
- os: macos-13
architecture: x32
steps:
- uses: actions/checkout@v4
- name: Setup Go ${{ matrix.version }} ${{ matrix.architecture }}
@ -70,8 +72,14 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
go: [1.17, 1.18, 1.19]
os: [macos-latest, windows-latest, ubuntu-latest, macos-13]
go: [1.21.13, 1.22.8, 1.23.2]
include:
- os: windows-latest
go: 1.20.14
exclude:
- os: windows-latest
go: 1.23.2
steps:
- name: Checkout
uses: actions/checkout@v4
@ -90,8 +98,8 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
go-version: [1.16, 1.17]
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
go-version: ['1.20', '1.21', '1.22', '1.23']
steps:
- uses: actions/checkout@v4
- name: Setup Go and check latest
@ -107,7 +115,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
steps:
- uses: actions/checkout@v4
- name: Setup Go and check latest
@ -115,7 +123,7 @@ jobs:
with:
go-version-file: __tests__/data/go.mod
- name: verify go
run: __tests__/verify-go.sh 1.14
run: __tests__/verify-go.sh 1.20.14
shell: bash
go-version-file-with-gowork:
@ -123,7 +131,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
steps:
- uses: actions/checkout@v4
- name: Setup Go and check latest
@ -131,17 +139,16 @@ jobs:
with:
go-version-file: __tests__/data/go.work
- name: verify go
run: __tests__/verify-go.sh 1.19
run: __tests__/verify-go.sh 1.21
shell: bash
setup-versions-from-manifest:
name: Setup ${{ matrix.go }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
go: [1.12.16, 1.13.11, 1.14.3]
os: [macos-latest, windows-latest, ubuntu-latest, macos-13]
go: [1.20.14, 1.21.10, 1.22.8, 1.23.2]
steps:
- name: Checkout
uses: actions/checkout@v4
@ -156,13 +163,12 @@ jobs:
shell: bash
setup-versions-from-dist:
name: Setup ${{ matrix.go }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
go: [1.9, 1.8.6]
os: [windows-latest, ubuntu-latest, macos-13]
go: [1.11.12]
steps:
- name: Checkout
uses: actions/checkout@v4
@ -181,14 +187,23 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
go-version: [1.16, 1.17]
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
go-version: [1.20.14, 1.21, 1.22, 1.23]
include:
- os: macos-latest
architecture: arm64
- os: ubuntu-latest
architecture: x64
- os: windows-latest
architecture: x64
- os: macos-13
architecture: x64
steps:
- uses: actions/checkout@v4
- name: Setup Go and check latest
uses: ./
with:
go-version: ${{ matrix.go-version }}
architecture: x64
architecture: ${{ matrix.architecture }}
- name: Verify Go
run: go version

View File

@ -1,6 +1,6 @@
---
name: undici
version: 5.28.3
version: 5.28.4
type: npm
summary: An HTTP/1.1 client, written from scratch for Node.js
homepage: https://undici.nodejs.org

View File

@ -209,3 +209,41 @@ describe('isCacheFeatureAvailable', () => {
expect(warningSpy).toHaveBeenCalledWith(warningMessage);
});
});
describe('isGhes', () => {
const pristineEnv = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {...pristineEnv};
});
afterAll(() => {
process.env = pristineEnv;
});
it('returns false when the GITHUB_SERVER_URL environment variable is not defined', async () => {
delete process.env['GITHUB_SERVER_URL'];
expect(cacheUtils.isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable is set to github.com', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://github.com';
expect(cacheUtils.isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable is set to a GitHub Enterprise Cloud-style URL', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://contoso.ghe.com';
expect(cacheUtils.isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable has a .localhost suffix', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://mock-github.localhost';
expect(cacheUtils.isGhes()).toBeFalsy();
});
it('returns true when the GITHUB_SERVER_URL environment variable is set to some other URL', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://src.onpremise.fabrikam.com';
expect(cacheUtils.isGhes()).toBeTruthy();
});
});

View File

@ -1,6 +1,6 @@
module example.com/mymodule
go 1.14
go 1.20
require (
example.com/othermodule v1.2.3

View File

@ -1,3 +1,3 @@
go 1.19
go 1.21
use .

View File

@ -57964,6 +57964,132 @@ function onConnectTimeout (socket) {
module.exports = buildConnector
/***/ }),
/***/ 4462:
/***/ ((module) => {
"use strict";
/** @type {Record<string, string | undefined>} */
const headerNameLowerCasedRecord = {}
// https://developer.mozilla.org/docs/Web/HTTP/Headers
const wellknownHeaderNames = [
'Accept',
'Accept-Encoding',
'Accept-Language',
'Accept-Ranges',
'Access-Control-Allow-Credentials',
'Access-Control-Allow-Headers',
'Access-Control-Allow-Methods',
'Access-Control-Allow-Origin',
'Access-Control-Expose-Headers',
'Access-Control-Max-Age',
'Access-Control-Request-Headers',
'Access-Control-Request-Method',
'Age',
'Allow',
'Alt-Svc',
'Alt-Used',
'Authorization',
'Cache-Control',
'Clear-Site-Data',
'Connection',
'Content-Disposition',
'Content-Encoding',
'Content-Language',
'Content-Length',
'Content-Location',
'Content-Range',
'Content-Security-Policy',
'Content-Security-Policy-Report-Only',
'Content-Type',
'Cookie',
'Cross-Origin-Embedder-Policy',
'Cross-Origin-Opener-Policy',
'Cross-Origin-Resource-Policy',
'Date',
'Device-Memory',
'Downlink',
'ECT',
'ETag',
'Expect',
'Expect-CT',
'Expires',
'Forwarded',
'From',
'Host',
'If-Match',
'If-Modified-Since',
'If-None-Match',
'If-Range',
'If-Unmodified-Since',
'Keep-Alive',
'Last-Modified',
'Link',
'Location',
'Max-Forwards',
'Origin',
'Permissions-Policy',
'Pragma',
'Proxy-Authenticate',
'Proxy-Authorization',
'RTT',
'Range',
'Referer',
'Referrer-Policy',
'Refresh',
'Retry-After',
'Sec-WebSocket-Accept',
'Sec-WebSocket-Extensions',
'Sec-WebSocket-Key',
'Sec-WebSocket-Protocol',
'Sec-WebSocket-Version',
'Server',
'Server-Timing',
'Service-Worker-Allowed',
'Service-Worker-Navigation-Preload',
'Set-Cookie',
'SourceMap',
'Strict-Transport-Security',
'Supports-Loading-Mode',
'TE',
'Timing-Allow-Origin',
'Trailer',
'Transfer-Encoding',
'Upgrade',
'Upgrade-Insecure-Requests',
'User-Agent',
'Vary',
'Via',
'WWW-Authenticate',
'X-Content-Type-Options',
'X-DNS-Prefetch-Control',
'X-Frame-Options',
'X-Permitted-Cross-Domain-Policies',
'X-Powered-By',
'X-Requested-With',
'X-XSS-Protection'
]
for (let i = 0; i < wellknownHeaderNames.length; ++i) {
const key = wellknownHeaderNames[i]
const lowerCasedKey = key.toLowerCase()
headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] =
lowerCasedKey
}
// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
Object.setPrototypeOf(headerNameLowerCasedRecord, null)
module.exports = {
wellknownHeaderNames,
headerNameLowerCasedRecord
}
/***/ }),
/***/ 8045:
@ -58796,6 +58922,7 @@ const { InvalidArgumentError } = __nccwpck_require__(8045)
const { Blob } = __nccwpck_require__(4300)
const nodeUtil = __nccwpck_require__(3837)
const { stringify } = __nccwpck_require__(3477)
const { headerNameLowerCasedRecord } = __nccwpck_require__(4462)
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v))
@ -59005,6 +59132,15 @@ function parseKeepAliveTimeout (val) {
return m ? parseInt(m[1], 10) * 1000 : null
}
/**
* Retrieves a header name and returns its lowercase value.
* @param {string | Buffer} value Header name
* @returns {string}
*/
function headerNameToString (value) {
return headerNameLowerCasedRecord[value] || value.toLowerCase()
}
function parseHeaders (headers, obj = {}) {
// For H2 support
if (!Array.isArray(headers)) return headers
@ -59276,6 +59412,7 @@ module.exports = {
isIterable,
isAsyncIterable,
isDestroyed,
headerNameToString,
parseRawHeaders,
parseHeaders,
parseKeepAliveTimeout,
@ -65923,14 +66060,18 @@ const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983
const assert = __nccwpck_require__(9491)
const { isUint8Array } = __nccwpck_require__(9830)
let supportedHashes = []
// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
/** @type {import('crypto')|undefined} */
let crypto
try {
crypto = __nccwpck_require__(6113)
const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']
supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash))
/* c8 ignore next 3 */
} catch {
}
function responseURL (response) {
@ -66458,66 +66599,56 @@ function bytesMatch (bytes, metadataList) {
return true
}
// 3. If parsedMetadata is the empty set, return true.
// 3. If response is not eligible for integrity validation, return false.
// TODO
// 4. If parsedMetadata is the empty set, return true.
if (parsedMetadata.length === 0) {
return true
}
// 4. Let metadata be the result of getting the strongest
// 5. Let metadata be the result of getting the strongest
// metadata from parsedMetadata.
const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo))
// get the strongest algorithm
const strongest = list[0].algo
// get all entries that use the strongest algorithm; ignore weaker
const metadata = list.filter((item) => item.algo === strongest)
const strongest = getStrongestMetadata(parsedMetadata)
const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest)
// 5. For each item in metadata:
// 6. For each item in metadata:
for (const item of metadata) {
// 1. Let algorithm be the alg component of item.
const algorithm = item.algo
// 2. Let expectedValue be the val component of item.
let expectedValue = item.hash
const expectedValue = item.hash
// See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e
// "be liberal with padding". This is annoying, and it's not even in the spec.
if (expectedValue.endsWith('==')) {
expectedValue = expectedValue.slice(0, -2)
}
// 3. Let actualValue be the result of applying algorithm to bytes.
let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64')
if (actualValue.endsWith('==')) {
actualValue = actualValue.slice(0, -2)
if (actualValue[actualValue.length - 1] === '=') {
if (actualValue[actualValue.length - 2] === '=') {
actualValue = actualValue.slice(0, -2)
} else {
actualValue = actualValue.slice(0, -1)
}
}
// 4. If actualValue is a case-sensitive match for expectedValue,
// return true.
if (actualValue === expectedValue) {
return true
}
let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url')
if (actualBase64URL.endsWith('==')) {
actualBase64URL = actualBase64URL.slice(0, -2)
}
if (actualBase64URL === expectedValue) {
if (compareBase64Mixed(actualValue, expectedValue)) {
return true
}
}
// 6. Return false.
// 7. Return false.
return false
}
// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options
// https://www.w3.org/TR/CSP2/#source-list-syntax
// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1
const parseHashWithOptions = /((?<algo>sha256|sha384|sha512)-(?<hash>[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i
const parseHashWithOptions = /(?<algo>sha256|sha384|sha512)-((?<hash>[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i
/**
* @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
@ -66531,8 +66662,6 @@ function parseMetadata (metadata) {
// 2. Let empty be equal to true.
let empty = true
const supportedHashes = crypto.getHashes()
// 3. For each token returned by splitting metadata on spaces:
for (const token of metadata.split(' ')) {
// 1. Set empty to false.
@ -66542,7 +66671,11 @@ function parseMetadata (metadata) {
const parsedToken = parseHashWithOptions.exec(token)
// 3. If token does not parse, continue to the next token.
if (parsedToken === null || parsedToken.groups === undefined) {
if (
parsedToken === null ||
parsedToken.groups === undefined ||
parsedToken.groups.algo === undefined
) {
// Note: Chromium blocks the request at this point, but Firefox
// gives a warning that an invalid integrity was given. The
// correct behavior is to ignore these, and subsequently not
@ -66551,11 +66684,11 @@ function parseMetadata (metadata) {
}
// 4. Let algorithm be the hash-algo component of token.
const algorithm = parsedToken.groups.algo
const algorithm = parsedToken.groups.algo.toLowerCase()
// 5. If algorithm is a hash function recognized by the user
// agent, add the parsed token to result.
if (supportedHashes.includes(algorithm.toLowerCase())) {
if (supportedHashes.includes(algorithm)) {
result.push(parsedToken.groups)
}
}
@ -66568,6 +66701,82 @@ function parseMetadata (metadata) {
return result
}
/**
* @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList
*/
function getStrongestMetadata (metadataList) {
// Let algorithm be the algo component of the first item in metadataList.
// Can be sha256
let algorithm = metadataList[0].algo
// If the algorithm is sha512, then it is the strongest
// and we can return immediately
if (algorithm[3] === '5') {
return algorithm
}
for (let i = 1; i < metadataList.length; ++i) {
const metadata = metadataList[i]
// If the algorithm is sha512, then it is the strongest
// and we can break the loop immediately
if (metadata.algo[3] === '5') {
algorithm = 'sha512'
break
// If the algorithm is sha384, then a potential sha256 or sha384 is ignored
} else if (algorithm[3] === '3') {
continue
// algorithm is sha256, check if algorithm is sha384 and if so, set it as
// the strongest
} else if (metadata.algo[3] === '3') {
algorithm = 'sha384'
}
}
return algorithm
}
function filterMetadataListByAlgorithm (metadataList, algorithm) {
if (metadataList.length === 1) {
return metadataList
}
let pos = 0
for (let i = 0; i < metadataList.length; ++i) {
if (metadataList[i].algo === algorithm) {
metadataList[pos++] = metadataList[i]
}
}
metadataList.length = pos
return metadataList
}
/**
* Compares two base64 strings, allowing for base64url
* in the second string.
*
* @param {string} actualValue always base64
* @param {string} expectedValue base64 or base64url
* @returns {boolean}
*/
function compareBase64Mixed (actualValue, expectedValue) {
if (actualValue.length !== expectedValue.length) {
return false
}
for (let i = 0; i < actualValue.length; ++i) {
if (actualValue[i] !== expectedValue[i]) {
if (
(actualValue[i] === '+' && expectedValue[i] === '-') ||
(actualValue[i] === '/' && expectedValue[i] === '_')
) {
continue
}
return false
}
}
return true
}
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
// TODO
@ -66983,7 +67192,8 @@ module.exports = {
urlHasHttpsScheme,
urlIsHttpHttpsScheme,
readAllBytes,
normalizeMethodRecord
normalizeMethodRecord,
parseMetadata
}
@ -69070,12 +69280,17 @@ function parseLocation (statusCode, headers) {
// https://tools.ietf.org/html/rfc7231#section-6.4.4
function shouldRemoveHeader (header, removeContent, unknownOrigin) {
return (
(header.length === 4 && header.toString().toLowerCase() === 'host') ||
(removeContent && header.toString().toLowerCase().indexOf('content-') === 0) ||
(unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') ||
(unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie')
)
if (header.length === 4) {
return util.headerNameToString(header) === 'host'
}
if (removeContent && util.headerNameToString(header).startsWith('content-')) {
return true
}
if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
const name = util.headerNameToString(header)
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
}
return false
}
// https://tools.ietf.org/html/rfc7231#section-6.4
@ -80960,7 +81175,11 @@ const getCacheDirectoryPath = (packageManagerInfo) => __awaiter(void 0, void 0,
exports.getCacheDirectoryPath = getCacheDirectoryPath;
function isGhes() {
const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
const hostname = ghUrl.hostname.trimEnd().toUpperCase();
const isGitHubHost = hostname === 'GITHUB.COM';
const isGitHubEnterpriseCloudHost = hostname.endsWith('.GHE.COM');
const isLocalHost = hostname.endsWith('.LOCALHOST');
return !isGitHubHost && !isGitHubEnterpriseCloudHost && !isLocalHost;
}
exports.isGhes = isGhes;
function isCacheFeatureAvailable() {

306
dist/setup/index.js vendored
View File

@ -64982,6 +64982,132 @@ function onConnectTimeout (socket) {
module.exports = buildConnector
/***/ }),
/***/ 4462:
/***/ ((module) => {
"use strict";
/** @type {Record<string, string | undefined>} */
const headerNameLowerCasedRecord = {}
// https://developer.mozilla.org/docs/Web/HTTP/Headers
const wellknownHeaderNames = [
'Accept',
'Accept-Encoding',
'Accept-Language',
'Accept-Ranges',
'Access-Control-Allow-Credentials',
'Access-Control-Allow-Headers',
'Access-Control-Allow-Methods',
'Access-Control-Allow-Origin',
'Access-Control-Expose-Headers',
'Access-Control-Max-Age',
'Access-Control-Request-Headers',
'Access-Control-Request-Method',
'Age',
'Allow',
'Alt-Svc',
'Alt-Used',
'Authorization',
'Cache-Control',
'Clear-Site-Data',
'Connection',
'Content-Disposition',
'Content-Encoding',
'Content-Language',
'Content-Length',
'Content-Location',
'Content-Range',
'Content-Security-Policy',
'Content-Security-Policy-Report-Only',
'Content-Type',
'Cookie',
'Cross-Origin-Embedder-Policy',
'Cross-Origin-Opener-Policy',
'Cross-Origin-Resource-Policy',
'Date',
'Device-Memory',
'Downlink',
'ECT',
'ETag',
'Expect',
'Expect-CT',
'Expires',
'Forwarded',
'From',
'Host',
'If-Match',
'If-Modified-Since',
'If-None-Match',
'If-Range',
'If-Unmodified-Since',
'Keep-Alive',
'Last-Modified',
'Link',
'Location',
'Max-Forwards',
'Origin',
'Permissions-Policy',
'Pragma',
'Proxy-Authenticate',
'Proxy-Authorization',
'RTT',
'Range',
'Referer',
'Referrer-Policy',
'Refresh',
'Retry-After',
'Sec-WebSocket-Accept',
'Sec-WebSocket-Extensions',
'Sec-WebSocket-Key',
'Sec-WebSocket-Protocol',
'Sec-WebSocket-Version',
'Server',
'Server-Timing',
'Service-Worker-Allowed',
'Service-Worker-Navigation-Preload',
'Set-Cookie',
'SourceMap',
'Strict-Transport-Security',
'Supports-Loading-Mode',
'TE',
'Timing-Allow-Origin',
'Trailer',
'Transfer-Encoding',
'Upgrade',
'Upgrade-Insecure-Requests',
'User-Agent',
'Vary',
'Via',
'WWW-Authenticate',
'X-Content-Type-Options',
'X-DNS-Prefetch-Control',
'X-Frame-Options',
'X-Permitted-Cross-Domain-Policies',
'X-Powered-By',
'X-Requested-With',
'X-XSS-Protection'
]
for (let i = 0; i < wellknownHeaderNames.length; ++i) {
const key = wellknownHeaderNames[i]
const lowerCasedKey = key.toLowerCase()
headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] =
lowerCasedKey
}
// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
Object.setPrototypeOf(headerNameLowerCasedRecord, null)
module.exports = {
wellknownHeaderNames,
headerNameLowerCasedRecord
}
/***/ }),
/***/ 8045:
@ -65814,6 +65940,7 @@ const { InvalidArgumentError } = __nccwpck_require__(8045)
const { Blob } = __nccwpck_require__(4300)
const nodeUtil = __nccwpck_require__(3837)
const { stringify } = __nccwpck_require__(3477)
const { headerNameLowerCasedRecord } = __nccwpck_require__(4462)
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v))
@ -66023,6 +66150,15 @@ function parseKeepAliveTimeout (val) {
return m ? parseInt(m[1], 10) * 1000 : null
}
/**
* Retrieves a header name and returns its lowercase value.
* @param {string | Buffer} value Header name
* @returns {string}
*/
function headerNameToString (value) {
return headerNameLowerCasedRecord[value] || value.toLowerCase()
}
function parseHeaders (headers, obj = {}) {
// For H2 support
if (!Array.isArray(headers)) return headers
@ -66294,6 +66430,7 @@ module.exports = {
isIterable,
isAsyncIterable,
isDestroyed,
headerNameToString,
parseRawHeaders,
parseHeaders,
parseKeepAliveTimeout,
@ -72941,14 +73078,18 @@ const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983
const assert = __nccwpck_require__(9491)
const { isUint8Array } = __nccwpck_require__(9830)
let supportedHashes = []
// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
/** @type {import('crypto')|undefined} */
let crypto
try {
crypto = __nccwpck_require__(6113)
const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']
supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash))
/* c8 ignore next 3 */
} catch {
}
function responseURL (response) {
@ -73476,66 +73617,56 @@ function bytesMatch (bytes, metadataList) {
return true
}
// 3. If parsedMetadata is the empty set, return true.
// 3. If response is not eligible for integrity validation, return false.
// TODO
// 4. If parsedMetadata is the empty set, return true.
if (parsedMetadata.length === 0) {
return true
}
// 4. Let metadata be the result of getting the strongest
// 5. Let metadata be the result of getting the strongest
// metadata from parsedMetadata.
const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo))
// get the strongest algorithm
const strongest = list[0].algo
// get all entries that use the strongest algorithm; ignore weaker
const metadata = list.filter((item) => item.algo === strongest)
const strongest = getStrongestMetadata(parsedMetadata)
const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest)
// 5. For each item in metadata:
// 6. For each item in metadata:
for (const item of metadata) {
// 1. Let algorithm be the alg component of item.
const algorithm = item.algo
// 2. Let expectedValue be the val component of item.
let expectedValue = item.hash
const expectedValue = item.hash
// See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e
// "be liberal with padding". This is annoying, and it's not even in the spec.
if (expectedValue.endsWith('==')) {
expectedValue = expectedValue.slice(0, -2)
}
// 3. Let actualValue be the result of applying algorithm to bytes.
let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64')
if (actualValue.endsWith('==')) {
actualValue = actualValue.slice(0, -2)
if (actualValue[actualValue.length - 1] === '=') {
if (actualValue[actualValue.length - 2] === '=') {
actualValue = actualValue.slice(0, -2)
} else {
actualValue = actualValue.slice(0, -1)
}
}
// 4. If actualValue is a case-sensitive match for expectedValue,
// return true.
if (actualValue === expectedValue) {
return true
}
let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url')
if (actualBase64URL.endsWith('==')) {
actualBase64URL = actualBase64URL.slice(0, -2)
}
if (actualBase64URL === expectedValue) {
if (compareBase64Mixed(actualValue, expectedValue)) {
return true
}
}
// 6. Return false.
// 7. Return false.
return false
}
// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options
// https://www.w3.org/TR/CSP2/#source-list-syntax
// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1
const parseHashWithOptions = /((?<algo>sha256|sha384|sha512)-(?<hash>[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i
const parseHashWithOptions = /(?<algo>sha256|sha384|sha512)-((?<hash>[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i
/**
* @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
@ -73549,8 +73680,6 @@ function parseMetadata (metadata) {
// 2. Let empty be equal to true.
let empty = true
const supportedHashes = crypto.getHashes()
// 3. For each token returned by splitting metadata on spaces:
for (const token of metadata.split(' ')) {
// 1. Set empty to false.
@ -73560,7 +73689,11 @@ function parseMetadata (metadata) {
const parsedToken = parseHashWithOptions.exec(token)
// 3. If token does not parse, continue to the next token.
if (parsedToken === null || parsedToken.groups === undefined) {
if (
parsedToken === null ||
parsedToken.groups === undefined ||
parsedToken.groups.algo === undefined
) {
// Note: Chromium blocks the request at this point, but Firefox
// gives a warning that an invalid integrity was given. The
// correct behavior is to ignore these, and subsequently not
@ -73569,11 +73702,11 @@ function parseMetadata (metadata) {
}
// 4. Let algorithm be the hash-algo component of token.
const algorithm = parsedToken.groups.algo
const algorithm = parsedToken.groups.algo.toLowerCase()
// 5. If algorithm is a hash function recognized by the user
// agent, add the parsed token to result.
if (supportedHashes.includes(algorithm.toLowerCase())) {
if (supportedHashes.includes(algorithm)) {
result.push(parsedToken.groups)
}
}
@ -73586,6 +73719,82 @@ function parseMetadata (metadata) {
return result
}
/**
* @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList
*/
function getStrongestMetadata (metadataList) {
// Let algorithm be the algo component of the first item in metadataList.
// Can be sha256
let algorithm = metadataList[0].algo
// If the algorithm is sha512, then it is the strongest
// and we can return immediately
if (algorithm[3] === '5') {
return algorithm
}
for (let i = 1; i < metadataList.length; ++i) {
const metadata = metadataList[i]
// If the algorithm is sha512, then it is the strongest
// and we can break the loop immediately
if (metadata.algo[3] === '5') {
algorithm = 'sha512'
break
// If the algorithm is sha384, then a potential sha256 or sha384 is ignored
} else if (algorithm[3] === '3') {
continue
// algorithm is sha256, check if algorithm is sha384 and if so, set it as
// the strongest
} else if (metadata.algo[3] === '3') {
algorithm = 'sha384'
}
}
return algorithm
}
function filterMetadataListByAlgorithm (metadataList, algorithm) {
if (metadataList.length === 1) {
return metadataList
}
let pos = 0
for (let i = 0; i < metadataList.length; ++i) {
if (metadataList[i].algo === algorithm) {
metadataList[pos++] = metadataList[i]
}
}
metadataList.length = pos
return metadataList
}
/**
* Compares two base64 strings, allowing for base64url
* in the second string.
*
* @param {string} actualValue always base64
* @param {string} expectedValue base64 or base64url
* @returns {boolean}
*/
function compareBase64Mixed (actualValue, expectedValue) {
if (actualValue.length !== expectedValue.length) {
return false
}
for (let i = 0; i < actualValue.length; ++i) {
if (actualValue[i] !== expectedValue[i]) {
if (
(actualValue[i] === '+' && expectedValue[i] === '-') ||
(actualValue[i] === '/' && expectedValue[i] === '_')
) {
continue
}
return false
}
}
return true
}
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
// TODO
@ -74001,7 +74210,8 @@ module.exports = {
urlHasHttpsScheme,
urlIsHttpHttpsScheme,
readAllBytes,
normalizeMethodRecord
normalizeMethodRecord,
parseMetadata
}
@ -76088,12 +76298,17 @@ function parseLocation (statusCode, headers) {
// https://tools.ietf.org/html/rfc7231#section-6.4.4
function shouldRemoveHeader (header, removeContent, unknownOrigin) {
return (
(header.length === 4 && header.toString().toLowerCase() === 'host') ||
(removeContent && header.toString().toLowerCase().indexOf('content-') === 0) ||
(unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') ||
(unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie')
)
if (header.length === 4) {
return util.headerNameToString(header) === 'host'
}
if (removeContent && util.headerNameToString(header).startsWith('content-')) {
return true
}
if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
const name = util.headerNameToString(header)
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
}
return false
}
// https://tools.ietf.org/html/rfc7231#section-6.4
@ -87830,6 +88045,7 @@ const cache_utils_1 = __nccwpck_require__(1678);
const restoreCache = (versionSpec, packageManager, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
const packageManagerInfo = yield (0, cache_utils_1.getPackageManagerInfo)(packageManager);
const platform = process.env.RUNNER_OS;
const arch = process.arch;
const cachePaths = yield (0, cache_utils_1.getCacheDirectoryPath)(packageManagerInfo);
const dependencyFilePath = cacheDependencyPath
? cacheDependencyPath
@ -87839,7 +88055,7 @@ const restoreCache = (versionSpec, packageManager, cacheDependencyPath) => __awa
throw new Error('Some specified paths were not resolved, unable to cache dependencies.');
}
const linuxVersion = process.env.RUNNER_OS === 'Linux' ? `${process.env.ImageOS}-` : '';
const primaryKey = `setup-go-${platform}-${linuxVersion}go-${versionSpec}-${fileHash}`;
const primaryKey = `setup-go-${platform}-${arch}-${linuxVersion}go-${versionSpec}-${fileHash}`;
core.debug(`primary key is ${primaryKey}`);
core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
const cacheKey = yield cache.restoreCache(cachePaths, primaryKey);
@ -87949,7 +88165,11 @@ const getCacheDirectoryPath = (packageManagerInfo) => __awaiter(void 0, void 0,
exports.getCacheDirectoryPath = getCacheDirectoryPath;
function isGhes() {
const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
const hostname = ghUrl.hostname.trimEnd().toUpperCase();
const isGitHubHost = hostname === 'GITHUB.COM';
const isGitHubEnterpriseCloudHost = hostname.endsWith('.GHE.COM');
const isLocalHost = hostname.endsWith('.LOCALHOST');
return !isGitHubHost && !isGitHubEnterpriseCloudHost && !isLocalHost;
}
exports.isGhes = isGhes;
function isCacheFeatureAvailable() {

28
package-lock.json generated
View File

@ -2214,12 +2214,12 @@
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@ -3175,9 +3175,9 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
@ -4559,12 +4559,12 @@
}
},
"node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"dependencies": {
"braces": "^3.0.2",
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@ -5739,9 +5739,9 @@
}
},
"node_modules/undici": {
"version": "5.28.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},

View File

@ -15,6 +15,7 @@ export const restoreCache = async (
) => {
const packageManagerInfo = await getPackageManagerInfo(packageManager);
const platform = process.env.RUNNER_OS;
const arch = process.arch;
const cachePaths = await getCacheDirectoryPath(packageManagerInfo);
@ -31,7 +32,7 @@ export const restoreCache = async (
const linuxVersion =
process.env.RUNNER_OS === 'Linux' ? `${process.env.ImageOS}-` : '';
const primaryKey = `setup-go-${platform}-${linuxVersion}go-${versionSpec}-${fileHash}`;
const primaryKey = `setup-go-${platform}-${arch}-${linuxVersion}go-${versionSpec}-${fileHash}`;
core.debug(`primary key is ${primaryKey}`);
core.saveState(State.CachePrimaryKey, primaryKey);

View File

@ -63,7 +63,13 @@ export function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
const hostname = ghUrl.hostname.trimEnd().toUpperCase();
const isGitHubHost = hostname === 'GITHUB.COM';
const isGitHubEnterpriseCloudHost = hostname.endsWith('.GHE.COM');
const isLocalHost = hostname.endsWith('.LOCALHOST');
return !isGitHubHost && !isGitHubEnterpriseCloudHost && !isLocalHost;
}
export function isCacheFeatureAvailable(): boolean {