Compare commits

..

16 Commits

Author SHA1 Message Date
JoannaaKL 780e24be34 Dont skip pages 2025-03-05 09:27:35 +00:00
Brian DeHamer ec9716b3cc Merge pull request #1969 from actions/bdehamer/workflow-ref
set workflow.ref provenance field from ref claim
2025-02-26 09:50:14 -08:00
Brian DeHamer 0bc338adab set workflow.ref provenance field from ref claim
Updates the `buildSLSAProvenancePredicate` function to populate the
`workflow.ref` field from the `ref` claim in the OIDC token.

Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-02-26 08:47:27 -08:00
Rob Herley 5378ea8eca Merge pull request #1968 from actions/robherley/cache/v4.0.2
cache: prep v4.0.2 release
2025-02-25 16:00:06 -05:00
Brian DeHamer b95b593ca5 Merge pull request #1957 from actions/bdehamer/update-undici
Bump undici to v5.28.5
2025-02-25 12:54:29 -08:00
Rob Herley 4fedf471b1 cache: prep v4.0.2 release 2025-02-25 15:03:37 -05:00
Rob Herley 1b9063ee0e Merge pull request #1966 from actions/robherley/wrap-create-cache-err
cache: wrap create failures in ReserveCacheError
2025-02-25 15:00:25 -05:00
Rob Herley d096588f08 cache: wrap create failures in ReserveCacheError 2025-02-25 12:49:08 -05:00
Yang Cao 662b9d91f5 Merge pull request #1963 from actions/yacaovsnc/release_2_2_2
Prepare artifact release 2.2.2
2025-02-20 16:29:30 -05:00
Yang Cao a62f530b6f Update package-lock.json 2025-02-20 21:20:28 +00:00
Yang Cao 2995cdf0a1 Prepare artifact release 2.2.2 2025-02-20 21:12:25 +00:00
Yang Cao f10f9c8217 Merge pull request #1962 from actions/yacaovsnc/set_default_concurrency_to_5
Default upload artifacts concurrency to 5
2025-02-20 13:56:30 -05:00
Yang Cao c26e6f3aba Default upload artifacts concurrency to 5 2025-02-20 17:03:29 +00:00
Rob Herley 2b08dc18f2 Merge pull request #1958 from actions/robherley/cache/v4.0.1
Update manifests & release notes for cache v4.0.1
2025-02-14 12:20:52 -05:00
Brian DeHamer 412108cd55 add undici to @actions/github dependencies
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-02-14 08:12:00 -08:00
Brian DeHamer 95e747361e bump undici to 5.28.5
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-02-14 08:02:10 -08:00
21 changed files with 129 additions and 121 deletions
+4
View File
@@ -1,5 +1,9 @@
# @actions/artifact Releases
### 2.2.2
- Default concurrency to 5 for uploading artifacts [#1962](https://github.com/actions/toolkit/pull/1962
### 2.2.1
- Add `ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY` and `ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS` environment variables [#1928](https://github.com/actions/toolkit/pull/1928)
+17 -15
View File
@@ -56,22 +56,30 @@ describe('uploadChunkTimeoutEnv', () => {
})
describe('uploadConcurrencyEnv', () => {
it('should return default 32 when cpu num is <= 4', () => {
it('Concurrency default to 5', () => {
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
expect(config.getConcurrency()).toBe(32)
expect(config.getConcurrency()).toBe(5)
})
it('should return 16 * num of cpu when cpu num is > 4', () => {
;(os.cpus as jest.Mock).mockReturnValue(new Array(6))
expect(config.getConcurrency()).toBe(96)
})
it('should return up to 300 max value', () => {
it('Concurrency max out at 300 on systems with many CPUs', () => {
;(os.cpus as jest.Mock).mockReturnValue(new Array(32))
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '301'
expect(config.getConcurrency()).toBe(300)
})
it('should return override value when ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY is set', () => {
it('Concurrency can be set to 32 when cpu num is <= 4', () => {
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '32'
expect(config.getConcurrency()).toBe(32)
})
it('Concurrency can be set 16 * num of cpu when cpu num is > 4', () => {
;(os.cpus as jest.Mock).mockReturnValue(new Array(6))
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '96'
expect(config.getConcurrency()).toBe(96)
})
it('Concurrency can be overridden by env var ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY', () => {
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '10'
expect(config.getConcurrency()).toBe(10)
@@ -92,10 +100,4 @@ describe('uploadConcurrencyEnv', () => {
config.getConcurrency()
}).toThrow()
})
it('cannot go over currency cap when override value is greater', () => {
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '40'
expect(config.getConcurrency()).toBe(32)
})
})
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@actions/artifact",
"version": "2.2.1",
"version": "2.2.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@actions/artifact",
"version": "2.2.1",
"version": "2.2.2",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/artifact",
"version": "2.2.1",
"version": "2.2.2",
"preview": true,
"description": "Actions artifact lib",
"keywords": [
@@ -70,14 +70,14 @@ export async function listArtifactsPublic(
createdAt: artifact.created_at ? new Date(artifact.created_at) : undefined
})
}
// Move to the next page
currentPageNumber++
// Iterate over any remaining pages
for (
currentPageNumber;
currentPageNumber < numberOfPages;
currentPageNumber++
) {
currentPageNumber++
debug(`Fetching page ${currentPageNumber} of artifact list`)
const {data: listArtifactResponse} =
@@ -45,10 +45,8 @@ export function getGitHubWorkspaceDir(): string {
return ghWorkspaceDir
}
// Mimics behavior of azcopy: https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-optimize
// If your machine has fewer than 5 CPUs, then the value of this variable is set to 32.
// Otherwise, the default value is equal to 16 multiplied by the number of CPUs. The maximum value of this variable is 300.
// This value can be lowered with ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY variable.
// The maximum value of concurrency is 300.
// This value can be changed with ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY variable.
export function getConcurrency(): number {
const numCPUs = os.cpus().length
let concurrencyCap = 32
@@ -68,15 +66,20 @@ export function getConcurrency(): number {
}
if (concurrency < concurrencyCap) {
info(
`Set concurrency based on the value set in ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY.`
)
return concurrency
}
info(
`ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY is higher than the cap of ${concurrencyCap} based on the number of cpus. Lowering it to the cap.`
`ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY is higher than the cap of ${concurrencyCap} based on the number of cpus. Set it to the maximum value allowed.`
)
return concurrencyCap
}
return concurrencyCap
// default concurrency to 5
return 5
}
export function getUploadChunkTimeout(): number {
+4
View File
@@ -1,5 +1,9 @@
# @actions/attest Releases
### 1.6.0
- Update `buildSLSAProvenancePredicate` to populate `workflow.ref` field from the `ref` claim in the OIDC token [#1969](https://github.com/actions/toolkit/pull/1969)
### 1.5.0
- Bump @actions/core from 1.10.1 to 1.11.1 [#1847](https://github.com/actions/toolkit/pull/1847)
@@ -1,47 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`provenance functions buildSLSAProvenancePredicate handle tags including "@" character 1`] = `
{
"params": {
"buildDefinition": {
"buildType": "https://actions.github.io/buildtypes/workflow/v1",
"externalParameters": {
"workflow": {
"path": ".github/workflows/main.yml",
"ref": "foo@1.0.0",
"repository": "https://foo.ghe.com/owner/repo",
},
},
"internalParameters": {
"github": {
"event_name": "push",
"repository_id": "repo-id",
"repository_owner_id": "owner-id",
"runner_environment": "github-hosted",
},
},
"resolvedDependencies": [
{
"digest": {
"gitCommit": "babca52ab0c93ae16539e5923cb0d7403b9a093b",
},
"uri": "git+https://foo.ghe.com/owner/repo@refs/heads/main",
},
],
},
"runDetails": {
"builder": {
"id": "https://foo.ghe.com/owner/workflows/.github/workflows/publish.yml@main",
},
"metadata": {
"invocationId": "https://foo.ghe.com/owner/repo/actions/runs/run-id/attempts/run-attempt",
},
},
},
"type": "https://slsa.dev/provenance/v1",
}
`;
exports[`provenance functions buildSLSAProvenancePredicate returns a provenance hydrated from an OIDC token 1`] = `
{
"params": {
@@ -50,7 +8,7 @@ exports[`provenance functions buildSLSAProvenancePredicate returns a provenance
"externalParameters": {
"workflow": {
"path": ".github/workflows/main.yml",
"ref": "main",
"ref": "refs/heads/main",
"repository": "https://foo.ghe.com/owner/repo",
},
},
@@ -75,16 +75,6 @@ describe('provenance functions', () => {
const predicate = await buildSLSAProvenancePredicate()
expect(predicate).toMatchSnapshot()
})
it('handle tags including "@" character', async () => {
nock.cleanAll()
await mockIssuer({
...claims,
workflow_ref: 'owner/repo/.github/workflows/main.yml@foo@1.0.0'
})
const predicate = await buildSLSAProvenancePredicate()
expect(predicate).toMatchSnapshot()
})
})
describe('attestProvenance', () => {
+16 -15
View File
@@ -1,12 +1,12 @@
{
"name": "@actions/attest",
"version": "1.5.0",
"version": "1.6.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@actions/attest",
"version": "1.5.0",
"version": "1.6.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.11.1",
@@ -22,7 +22,7 @@
"@sigstore/rekor-types": "^3.0.0",
"@types/jsonwebtoken": "^9.0.6",
"nock": "^13.5.1",
"undici": "^5.28.4"
"undici": "^5.28.5"
}
},
"node_modules/@actions/core": {
@@ -783,9 +783,9 @@
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -1657,9 +1657,10 @@
}
},
"node_modules/undici": {
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"version": "5.28.5",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
"license": "MIT",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
@@ -2454,9 +2455,9 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -3047,9 +3048,9 @@
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"undici": {
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"version": "5.28.5",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
"requires": {
"@fastify/busboy": "^2.0.0"
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/attest",
"version": "1.5.0",
"version": "1.6.0",
"description": "Actions attestation lib",
"keywords": [
"github",
@@ -39,7 +39,7 @@
"@sigstore/rekor-types": "^3.0.0",
"@types/jsonwebtoken": "^9.0.6",
"nock": "^13.5.1",
"undici": "^5.28.4"
"undici": "^5.28.5"
},
"dependencies": {
"@actions/core": "^1.11.1",
+2 -4
View File
@@ -30,11 +30,9 @@ export const buildSLSAProvenancePredicate = async (
// Split just the path and ref from the workflow string.
// owner/repo/.github/workflows/main.yml@main =>
// .github/workflows/main.yml, main
const [workflowPath, ...workflowRefChunks] = claims.workflow_ref
const [workflowPath] = claims.workflow_ref
.replace(`${claims.repository}/`, '')
.split('@')
// Handle case where tag contains `@` (e.g: when using changesets in a monorepo context),
const workflowRef = workflowRefChunks.join('@')
return {
type: SLSA_PREDICATE_V1_TYPE,
@@ -43,7 +41,7 @@ export const buildSLSAProvenancePredicate = async (
buildType: GITHUB_BUILD_TYPE,
externalParameters: {
workflow: {
ref: workflowRef,
ref: claims.ref,
repository: `${serverURL}/${claims.repository}`,
path: workflowPath
}
+4
View File
@@ -1,5 +1,9 @@
# @actions/cache Releases
### 4.0.2
- Wrap create failures in ReserveCacheError [#1966](https://github.com/actions/toolkit/pull/1966)
### 4.0.1
- Remove runtime dependency on `twirp-ts` [#1947](https://github.com/actions/toolkit/pull/1947)
+36 -3
View File
@@ -92,14 +92,14 @@ test('save with large cache outputs should fail using', async () => {
expect(getCompressionMock).toHaveBeenCalledTimes(1)
})
test('create cache entry failure', async () => {
test('create cache entry failure on non-ok response', async () => {
const paths = ['node_modules']
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const infoLogMock = jest.spyOn(core, 'info')
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(Promise.resolve({ok: false, signedUploadUrl: ''}))
.mockResolvedValue({ok: false, signedUploadUrl: ''})
const createTarMock = jest.spyOn(tar, 'createTar')
const finalizeCacheEntryMock = jest.spyOn(
@@ -109,7 +109,7 @@ test('create cache entry failure', async () => {
const compression = CompressionMethod.Zstd
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
.mockResolvedValueOnce(compression)
const archiveFileSize = 1024
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
@@ -133,6 +133,39 @@ test('create cache entry failure', async () => {
expect(saveCacheMock).toHaveBeenCalledTimes(0)
})
test('create cache entry fails on rejected promise', async () => {
const paths = ['node_modules']
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const infoLogMock = jest.spyOn(core, 'info')
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockRejectedValue(new Error('Failed to create cache entry'))
const createTarMock = jest.spyOn(tar, 'createTar')
const compression = CompressionMethod.Zstd
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockResolvedValueOnce(compression)
const archiveFileSize = 1024
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(archiveFileSize)
const cacheId = await saveCache(paths, key)
expect(cacheId).toBe(-1)
expect(infoLogMock).toHaveBeenCalledWith(
`Failed to save: Unable to reserve cache with key ${key}, another job may be creating this cache.`
)
expect(createCacheEntryMock).toHaveBeenCalledWith({
key,
version: cacheUtils.getCacheVersion(paths, compression)
})
expect(createTarMock).toHaveBeenCalledTimes(1)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
})
test('save cache fails if a signedUploadURL was not passed', async () => {
const paths = 'node_modules'
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@actions/cache",
"version": "4.0.1",
"version": "4.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@actions/cache",
"version": "4.0.1",
"version": "4.0.2",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.11.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/cache",
"version": "4.0.1",
"version": "4.0.2",
"preview": true,
"description": "Actions cache lib",
"keywords": [
+11 -3
View File
@@ -525,8 +525,16 @@ async function saveCacheV2(
version
}
const response = await twirpClient.CreateCacheEntry(request)
if (!response.ok) {
let signedUploadUrl
try {
const response = await twirpClient.CreateCacheEntry(request)
if (!response.ok) {
throw new Error('Response was not ok')
}
signedUploadUrl = response.signedUploadUrl
} catch (error) {
core.debug(`Failed to reserve cache: ${error}`)
throw new ReserveCacheError(
`Unable to reserve cache with key ${key}, another job may be creating this cache.`
)
@@ -536,7 +544,7 @@ async function saveCacheV2(
await cacheHttpClient.saveCache(
cacheId,
archivePath,
response.signedUploadUrl,
signedUploadUrl,
options
)
+9 -7
View File
@@ -12,7 +12,8 @@
"@actions/http-client": "^2.2.0",
"@octokit/core": "^5.0.1",
"@octokit/plugin-paginate-rest": "^9.0.0",
"@octokit/plugin-rest-endpoint-methods": "^10.0.0"
"@octokit/plugin-rest-endpoint-methods": "^10.0.0",
"undici": "^5.28.5"
},
"devDependencies": {
"proxy": "^2.1.1"
@@ -346,9 +347,10 @@
}
},
"node_modules/undici": {
"version": "5.25.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
"integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
"version": "5.28.5",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
"license": "MIT",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
@@ -619,9 +621,9 @@
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"undici": {
"version": "5.25.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
"integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
"version": "5.28.5",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
"requires": {
"@fastify/busboy": "^2.0.0"
}
+3 -2
View File
@@ -41,9 +41,10 @@
"@actions/http-client": "^2.2.0",
"@octokit/core": "^5.0.1",
"@octokit/plugin-paginate-rest": "^9.0.0",
"@octokit/plugin-rest-endpoint-methods": "^10.0.0"
"@octokit/plugin-rest-endpoint-methods": "^10.0.0",
"undici": "^5.28.5"
},
"devDependencies": {
"proxy": "^2.1.1"
}
}
}
+1 -1
View File
@@ -10,7 +10,7 @@
"license": "MIT",
"dependencies": {
"tunnel": "^0.0.6",
"undici": "^5.25.5"
"undici": "^5.28.5"
},
"devDependencies": {
"@types/node": "20.7.1",
+2 -2
View File
@@ -46,6 +46,6 @@
},
"dependencies": {
"tunnel": "^0.0.6",
"undici": "^5.25.5"
"undici": "^5.28.5"
}
}
}