Skip to content

Commit d044035

Browse files
committed
Allow changing default cache file size limit
Fixes #1932 Signed-off-by: Voplica <[email protected]>
1 parent 1f7c2c7 commit d044035

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ packages/*/__tests__/_temp/
55
.DS_Store
66
*.xar
77
packages/*/audit.json
8+
.idea

packages/cache/__tests__/saveCache.test.ts

+39-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as core from '@actions/core'
22
import * as path from 'path'
3-
import {saveCache} from '../src/cache'
3+
import {saveCache, setFileSizeLimit} from '../src/cache'
44
import * as cacheHttpClient from '../src/internal/cacheHttpClient'
55
import * as cacheUtils from '../src/internal/cacheUtils'
66
import * as config from '../src/internal/config'
7-
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
7+
import {CacheFilename, CacheFileSizeLimit, CompressionMethod} from '../src/internal/constants'
88
import * as tar from '../src/internal/tar'
99
import {TypedResponse} from '@actions/http-client/lib/interfaces'
1010
import {
@@ -19,6 +19,7 @@ jest.mock('../src/internal/config')
1919
jest.mock('../src/internal/tar')
2020

2121
beforeAll(() => {
22+
setFileSizeLimit(CacheFileSizeLimit)
2223
jest.spyOn(console, 'log').mockImplementation(() => {})
2324
jest.spyOn(core, 'debug').mockImplementation(() => {})
2425
jest.spyOn(core, 'info').mockImplementation(() => {})
@@ -79,6 +80,42 @@ test('save with large cache outputs should fail', async () => {
7980
expect(getCompressionMock).toHaveBeenCalledTimes(1)
8081
})
8182

83+
test('save with small cache outputs should fail on changed limit', async () => {
84+
setFileSizeLimit(100 * 1024 * 1024) // set default limit to 100 MB
85+
const filePath = 'node_modules'
86+
const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
87+
const cachePaths = [path.resolve(filePath)]
88+
89+
const createTarMock = jest.spyOn(tar, 'createTar')
90+
const logWarningMock = jest.spyOn(core, 'warning')
91+
92+
const cacheSize = 1024 * 1024 * 1024 //1GB, over the 100MB limit
93+
jest
94+
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
95+
.mockReturnValueOnce(cacheSize)
96+
const compression = CompressionMethod.Gzip
97+
const getCompressionMock = jest
98+
.spyOn(cacheUtils, 'getCompressionMethod')
99+
.mockReturnValueOnce(Promise.resolve(compression))
100+
101+
const cacheId = await saveCache([filePath], primaryKey)
102+
expect(cacheId).toBe(-1)
103+
expect(logWarningMock).toHaveBeenCalledTimes(1)
104+
expect(logWarningMock).toHaveBeenCalledWith(
105+
'Failed to save: Cache size of ~1024 MB (1073741824 B) is over the 100MB limit, not saving cache.'
106+
)
107+
108+
const archiveFolder = '/foo/bar'
109+
110+
expect(createTarMock).toHaveBeenCalledTimes(1)
111+
expect(createTarMock).toHaveBeenCalledWith(
112+
archiveFolder,
113+
cachePaths,
114+
compression
115+
)
116+
expect(getCompressionMock).toHaveBeenCalledTimes(1)
117+
})
118+
82119
test('save with large cache outputs should fail in GHES with error message', async () => {
83120
const filePath = 'node_modules'
84121
const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'

packages/cache/src/cache.ts

+22-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ function checkKey(key: string): void {
5151
}
5252
}
5353

54+
let fileSizeLimit = CacheFileSizeLimit // default 10GB per repo limit
55+
let fileSizeLimitStr = formatBytes(fileSizeLimit)
56+
57+
export function setFileSizeLimit(newFileSizeLimit: number){
58+
fileSizeLimit = newFileSizeLimit
59+
fileSizeLimitStr = formatBytes(newFileSizeLimit)
60+
}
61+
62+
export function formatBytes(bytes: number): string {
63+
if (bytes === 0) return "0 Bytes";
64+
65+
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
66+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
67+
const value = bytes / Math.pow(1024, i);
68+
69+
return `${value.toFixed(0)}${sizes[i]}`;
70+
}
71+
5472
/**
5573
* isFeatureAvailable to check the presence of Actions cache service
5674
*
@@ -385,7 +403,7 @@ async function saveCacheV1(
385403
if (core.isDebug()) {
386404
await listTar(archivePath, compressionMethod)
387405
}
388-
const fileSizeLimit = 10 * 1024 * 1024 * 1024 // 10GB per repo limit
406+
389407
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath)
390408
core.debug(`File Size: ${archiveFileSize}`)
391409

@@ -394,7 +412,7 @@ async function saveCacheV1(
394412
throw new Error(
395413
`Cache size of ~${Math.round(
396414
archiveFileSize / (1024 * 1024)
397-
)} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`
415+
)} MB (${archiveFileSize} B) is over the ${fileSizeLimitStr} limit, not saving cache.`
398416
)
399417
}
400418

@@ -503,11 +521,11 @@ async function saveCacheV2(
503521
core.debug(`File Size: ${archiveFileSize}`)
504522

505523
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
506-
if (archiveFileSize > CacheFileSizeLimit && !isGhes()) {
524+
if (archiveFileSize > fileSizeLimit && !isGhes()) {
507525
throw new Error(
508526
`Cache size of ~${Math.round(
509527
archiveFileSize / (1024 * 1024)
510-
)} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`
528+
)} MB (${archiveFileSize} B) is over the ${fileSizeLimitStr} limit, not saving cache.`
511529
)
512530
}
513531

0 commit comments

Comments
 (0)