diff --git a/packages/cmd/src/commands/cache/index.ts b/packages/cmd/src/commands/cache/index.ts index 88fbac8..638a09b 100644 --- a/packages/cmd/src/commands/cache/index.ts +++ b/packages/cmd/src/commands/cache/index.ts @@ -3,7 +3,8 @@ import { dim } from '@logger'; import chalk from 'chalk'; import { getCacheGetHandler } from './get'; import { - continueOption, + continueGetOption, + continueSetOption, debugOption, idOption, matrixIndexOption, @@ -63,6 +64,7 @@ export const getCacheSetCommand = () => { .addOption(pwOutputDirOption) .addOption(matrixIndexOption) .addOption(matrixTotalOption) + .addOption(continueSetOption) .action(getCacheSetHandler); return command; @@ -80,7 +82,7 @@ export const getCacheGetCommand = () => { .addOption(debugOption) .addOption(matrixIndexOption) .addOption(matrixTotalOption) - .addOption(continueOption) + .addOption(continueGetOption) .action(getCacheGetHandler); return command; diff --git a/packages/cmd/src/commands/cache/options.ts b/packages/cmd/src/commands/cache/options.ts index 312ebfd..a131785 100644 --- a/packages/cmd/src/commands/cache/options.ts +++ b/packages/cmd/src/commands/cache/options.ts @@ -73,7 +73,12 @@ function validatePositiveInteger(value: string) { return parsedValue; } -export const continueOption = new Option( +export const continueGetOption = new Option( '--continue', 'Continue the script execution if the cache is not found' ).default(false); + +export const continueSetOption = new Option( + '--continue', + 'Continue the script execution if upload paths are not found' +).default(false); diff --git a/packages/cmd/src/config/cache/config.ts b/packages/cmd/src/config/cache/config.ts index 133d417..39a7276 100644 --- a/packages/cmd/src/config/cache/config.ts +++ b/packages/cmd/src/config/cache/config.ts @@ -28,6 +28,7 @@ export type CacheSetCommandConfig = CacheCommandConfig & CommonConfig & { path?: string[]; pwOutputDir?: string; + continue?: boolean; }; export type CacheGetCommandConfig = CacheCommandConfig & diff --git a/packages/cmd/src/config/cache/env.ts b/packages/cmd/src/config/cache/env.ts index 768e22d..e387cb8 100644 --- a/packages/cmd/src/config/cache/env.ts +++ b/packages/cmd/src/config/cache/env.ts @@ -42,6 +42,10 @@ const cacheSetCommandConfigKeys = { name: 'Matrix total', cli: '--matrix-total', }, + continue: { + name: 'Continue when upload path missing', + cli: '--continue', + }, } as const; const cacheGetCommandConfigKeys = { diff --git a/packages/cmd/src/config/cache/options.ts b/packages/cmd/src/config/cache/options.ts index 4681743..389acb3 100644 --- a/packages/cmd/src/config/cache/options.ts +++ b/packages/cmd/src/config/cache/options.ts @@ -30,5 +30,6 @@ export function cacheSetCommandOptsToConfig( debug: options.debug, matrixIndex: options.matrixIndex, matrixTotal: options.matrixTotal, + continue: options.continue, }; } diff --git a/packages/cmd/src/services/cache/__tests__/set.spec.ts b/packages/cmd/src/services/cache/__tests__/set.spec.ts index c447815..2067c90 100644 --- a/packages/cmd/src/services/cache/__tests__/set.spec.ts +++ b/packages/cmd/src/services/cache/__tests__/set.spec.ts @@ -7,7 +7,7 @@ import { getCacheCommandConfig, } from '../../../config/cache'; import { getCI } from '../../../env/ciProvider'; -import { success } from '../../../logger'; +import { success, warnWithNoTrace } from '../../../logger'; import { zipFilesToBuffer } from '../fs'; import { createMeta } from '../lib'; import { sendBuffer } from '../network'; @@ -79,15 +79,40 @@ describe('handleSetCache', () => { await expect(handleSetCache()).rejects.toThrow('Config is missing!'); }); - it('should throw an error if no paths available to upload', async () => { + const testCacheNoPathsError = async (continueOnNoPaths: boolean) => { + (mockConfig.values as CacheCommandConfig & CacheSetCommandConfig).continue = + continueOnNoPaths; + const axiosError = { response: { status: 404 } }; vi.mocked(getUploadPaths).mockResolvedValue([]); vi.mocked(getCacheCommandConfig).mockReturnValue({ ...mockConfig, - values: { ...mockConfig.values, preset: undefined, path: [] }, + values: { + ...mockConfig.values, + preset: undefined, + path: [], + }, }); - await expect(handleSetCache()).rejects.toThrow( - 'No paths available to upload' - ); + + if (continueOnNoPaths) { + await handleSetCache(); + expect(warnWithNoTrace).toHaveBeenCalledWith( + `No files available to upload: ` + ); + expect(createCache).toHaveBeenCalled(); + } else { + await expect(handleSetCache()).rejects.toThrow( + `No files available to upload: ` + ); + expect(warnWithNoTrace).not.toHaveBeenCalled(); + } + }; + + it('should throw an error if no paths available to upload and continueOnNoPaths is false', async () => { + await testCacheNoPathsError(false); + }); + + it('should warn and continue if no paths available to upload and continueOnNoPaths is true', async () => { + await testCacheNoPathsError(true); }); it('should call filterPaths and zipFilesToBuffer', async () => { diff --git a/packages/cmd/src/services/cache/set.ts b/packages/cmd/src/services/cache/set.ts index 58c366f..2d16cbc 100644 --- a/packages/cmd/src/services/cache/set.ts +++ b/packages/cmd/src/services/cache/set.ts @@ -4,7 +4,7 @@ import { createCache } from '../../api'; import { PRESETS } from '../../commands/cache/options'; import { getCacheCommandConfig } from '../../config/cache'; import { getCI } from '../../env/ciProvider'; -import { dim, info, success } from '../../logger'; +import { dim, info, success, warnWithNoTrace } from '../../logger'; import { zipFilesToBuffer } from './fs'; import { createMeta } from './lib'; import { @@ -20,18 +20,31 @@ export async function handleSetCache() { throw new Error('Config is missing!'); } - const { recordKey, id, preset, pwOutputDir, matrixIndex, matrixTotal } = - config.values; + const { + recordKey, + id, + preset, + pwOutputDir, + matrixIndex, + matrixTotal, + continue: continueOnNoUpload, + } = config.values; const uploadPaths = await getUploadPaths(config.values.path); + const configUploadPaths: (string | undefined)[] = config.values.path || []; const ci = getCI(); if (preset === PRESETS.lastRun) { + configUploadPaths.push(pwOutputDir); uploadPaths.push(...(await getLastRunFilePaths(pwOutputDir))); } if (uploadPaths.length === 0) { - throw new Error('No paths available to upload'); + const message = `No files available to upload: ${configUploadPaths.filter(Boolean).join(',')}`; + if (!continueOnNoUpload) { + throw new Error(message); + } + warnWithNoTrace(message); } const result = await createCache({ @@ -45,13 +58,15 @@ export async function handleSetCache() { }); debug('Cache upload url created', { result }); - await handleArchiveUpload({ - archive: await zipFilesToBuffer(uploadPaths), - cacheId: result.cacheId, - uploadUrl: result.uploadUrl, - }); + if (uploadPaths.length > 0) { + await handleArchiveUpload({ + archive: await zipFilesToBuffer(uploadPaths), + cacheId: result.cacheId, + uploadUrl: result.uploadUrl, + }); - info(uploadPaths.map((path) => `${dim('- uploading')} ${path}`).join('\n')); + info(uploadPaths.map((path) => `${dim('- uploading')} ${path}`).join('\n')); + } await handleMetaUpload({ meta: createMeta({