mirror of
https://github.com/actions/cache.git
synced 2026-06-06 17:14:21 +00:00
feat: add path validation options to restore action
This commit is contained in:
parent
27d5ce7f10
commit
dabc4c2ca1
25 changed files with 201047 additions and 164350 deletions
119
__tests__/__mocks__/actions-cache.ts
Normal file
119
__tests__/__mocks__/actions-cache.ts
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* Local CommonJS stub for the `@actions/cache` toolkit package.
|
||||
*
|
||||
* The published toolkit is an ESM-only package, which Jest's CJS resolver
|
||||
* cannot load directly. The action's runtime is bundled by `@vercel/ncc`
|
||||
* (which handles ESM deps), but Jest tests run uncompiled and therefore
|
||||
* need a CJS-compatible surface to import.
|
||||
*
|
||||
* This file re-implements just the public surface that the action's source
|
||||
* code imports, with no-op implementations. Tests use `jest.spyOn` or
|
||||
* `jest.mock("@actions/cache")` to override the implementations as needed.
|
||||
*
|
||||
* Wired up via `moduleNameMapper` in `jest.config.js`.
|
||||
*
|
||||
* Types are pulled from the real `@actions/cache` package via type-only
|
||||
* imports, so a TypeScript build (via `tsc --noEmit` or ts-jest) verifies
|
||||
* that the stub's runtime surface still satisfies the real package's
|
||||
* signatures — a signature drift (renamed parameter, added property,
|
||||
* changed return type) will surface here as a compile error rather than
|
||||
* as a silent test-only behavior change. `import type` is fully erased at
|
||||
* compile time, so the Jest `moduleNameMapper` redirect for this file is
|
||||
* not affected at runtime (no self-referential require loop).
|
||||
*/
|
||||
|
||||
import type * as Cache from "@actions/cache";
|
||||
|
||||
// Re-export the toolkit's types so consumers of this stub and consumers of
|
||||
// the real package see identical types — there is no second source of truth.
|
||||
export type {
|
||||
CacheIntegrityErrorCode,
|
||||
DownloadOptions,
|
||||
PathValidationMode,
|
||||
PathValidationViolation,
|
||||
UploadOptions
|
||||
} from "@actions/cache";
|
||||
|
||||
// Each `typeof Cache.X` annotation forces the local implementation to be
|
||||
// assignable to the real package's exported signature.
|
||||
|
||||
export const ValidationError: typeof Cache.ValidationError = class extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "ValidationError";
|
||||
}
|
||||
};
|
||||
|
||||
export const ReserveCacheError: typeof Cache.ReserveCacheError = class extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "ReserveCacheError";
|
||||
}
|
||||
};
|
||||
|
||||
export const FinalizeCacheError: typeof Cache.FinalizeCacheError = class extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "FinalizeCacheError";
|
||||
}
|
||||
};
|
||||
|
||||
export const CacheIntegrityError: typeof Cache.CacheIntegrityError = class extends Error {
|
||||
readonly code: Cache.CacheIntegrityErrorCode;
|
||||
readonly violations?: Cache.PathValidationViolation[];
|
||||
constructor(
|
||||
code: Cache.CacheIntegrityErrorCode,
|
||||
message: string,
|
||||
violations?: Cache.PathValidationViolation[]
|
||||
) {
|
||||
super(message);
|
||||
this.name = "CacheIntegrityError";
|
||||
this.code = code;
|
||||
this.violations = violations;
|
||||
}
|
||||
};
|
||||
|
||||
export const isFeatureAvailable: typeof Cache.isFeatureAvailable = () => true;
|
||||
|
||||
function checkKey(key: string): void {
|
||||
if (key.length > 512) {
|
||||
throw new ValidationError(
|
||||
`Key Validation Error: ${key} cannot be larger than 512 characters.`
|
||||
);
|
||||
}
|
||||
const regex = /^[^,]*$/;
|
||||
if (!regex.test(key)) {
|
||||
throw new ValidationError(
|
||||
`Key Validation Error: ${key} cannot contain commas.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const restoreCache: typeof Cache.restoreCache = async (
|
||||
_paths,
|
||||
primaryKey,
|
||||
restoreKeys,
|
||||
_options,
|
||||
_enableCrossOsArchive
|
||||
) => {
|
||||
const keys = [primaryKey, ...(restoreKeys ?? [])];
|
||||
if (keys.length > 10) {
|
||||
throw new ValidationError(
|
||||
`Key Validation Error: Keys are limited to a maximum of 10.`
|
||||
);
|
||||
}
|
||||
for (const key of keys) {
|
||||
checkKey(key);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const saveCache: typeof Cache.saveCache = async (
|
||||
_paths,
|
||||
key,
|
||||
_options,
|
||||
_enableCrossOsArchive
|
||||
) => {
|
||||
checkKey(key);
|
||||
return -1;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue