mirror of
https://github.com/actions/cache.git
synced 2025-02-23 03:10:27 +00:00
Allow updating caches
This commit is contained in:
parent
36f1e144e1
commit
d69c349a03
7 changed files with 3802 additions and 12803 deletions
|
@ -34,6 +34,10 @@ inputs:
|
||||||
save-always does not work as intended and will be removed in a future release.
|
save-always does not work as intended and will be removed in a future release.
|
||||||
A separate `actions/cache/restore` step should be used instead.
|
A separate `actions/cache/restore` step should be used instead.
|
||||||
See https://github.com/actions/cache/tree/main/save#always-save-cache for more details.
|
See https://github.com/actions/cache/tree/main/save#always-save-cache for more details.
|
||||||
|
refresh-cache:
|
||||||
|
description: 'Whether to try and refresh existing caches (requires GITHUB_TOKEN to be present in env)'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
outputs:
|
outputs:
|
||||||
cache-hit:
|
cache-hit:
|
||||||
description: 'A boolean value to indicate an exact match was found for the primary key'
|
description: 'A boolean value to indicate an exact match was found for the primary key'
|
||||||
|
|
16520
package-lock.json
generated
16520
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -26,7 +26,8 @@
|
||||||
"@actions/cache": "^4.0.0",
|
"@actions/cache": "^4.0.0",
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^1.11.1",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/io": "^1.1.3"
|
"@actions/io": "^1.1.2",
|
||||||
|
"@octokit/action": "^4.0.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
|
|
|
@ -15,6 +15,10 @@ inputs:
|
||||||
description: 'An optional boolean when enabled, allows windows runners to save caches that can be restored on other platforms'
|
description: 'An optional boolean when enabled, allows windows runners to save caches that can be restored on other platforms'
|
||||||
default: 'false'
|
default: 'false'
|
||||||
required: false
|
required: false
|
||||||
|
refresh-cache:
|
||||||
|
description: 'An optional boolean, when enabled it will result in a matched key being deleted after being restored, allowing it to be reused with refreshed/updated content. Default: false'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
runs:
|
runs:
|
||||||
using: 'node20'
|
using: 'node20'
|
||||||
main: '../dist/save-only/index.js'
|
main: '../dist/save-only/index.js'
|
||||||
|
|
|
@ -5,7 +5,8 @@ export enum Inputs {
|
||||||
UploadChunkSize = "upload-chunk-size", // Input for cache, save action
|
UploadChunkSize = "upload-chunk-size", // Input for cache, save action
|
||||||
EnableCrossOsArchive = "enableCrossOsArchive", // Input for cache, restore, save action
|
EnableCrossOsArchive = "enableCrossOsArchive", // Input for cache, restore, save action
|
||||||
FailOnCacheMiss = "fail-on-cache-miss", // Input for cache, restore action
|
FailOnCacheMiss = "fail-on-cache-miss", // Input for cache, restore action
|
||||||
LookupOnly = "lookup-only" // Input for cache, restore action
|
LookupOnly = "lookup-only", // Input for cache, restore action
|
||||||
|
RefreshCache = "refresh-cache" // Input for cache, save action
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Outputs {
|
export enum Outputs {
|
||||||
|
|
|
@ -43,16 +43,39 @@ export async function saveImpl(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If matched restore key is same as primary key, then do not save cache
|
const refreshCache: boolean = utils.getInputAsBool(
|
||||||
// NO-OP in case of SaveOnly action
|
Inputs.RefreshCache,
|
||||||
|
{ required: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// If matched restore key is same as primary key, either try to refresh the cache, or just notify and do not save (NO-OP in case of SaveOnly action)
|
||||||
|
|
||||||
const restoredKey = stateProvider.getCacheState();
|
const restoredKey = stateProvider.getCacheState();
|
||||||
|
|
||||||
if (utils.isExactKeyMatch(primaryKey, restoredKey)) {
|
if (utils.isExactKeyMatch(primaryKey, restoredKey)) {
|
||||||
|
const { GITHUB_TOKEN, GITHUB_REPOSITORY } = process.env || null;
|
||||||
|
if (GITHUB_TOKEN && GITHUB_REPOSITORY && refreshCache === true) {
|
||||||
|
core.info(
|
||||||
|
`Cache hit occurred on the primary key ${primaryKey}, attempting to refresh the contents of the cache.`
|
||||||
|
);
|
||||||
|
const [_owner, _repo] = GITHUB_REPOSITORY.split(`/`);
|
||||||
|
if (_owner && _repo) {
|
||||||
|
await utils.deleteCacheByKey(primaryKey, _owner, _repo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (refreshCache === true) {
|
||||||
|
utils.logWarning(
|
||||||
|
`Can't refresh cache, either the repository info or a valid token are missing.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
core.info(
|
core.info(
|
||||||
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const cachePaths = utils.getInputAsArray(Inputs.Path, {
|
const cachePaths = utils.getInputAsArray(Inputs.Path, {
|
||||||
required: true
|
required: true
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import * as cache from "@actions/cache";
|
import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
import { RequestError } from "@octokit/request-error"
|
||||||
|
import { OctokitResponse } from "@octokit/types"
|
||||||
|
|
||||||
import { RefKey } from "../constants";
|
import { RefKey } from "../constants";
|
||||||
|
const { Octokit } = require("@octokit/action");
|
||||||
|
|
||||||
export function isGhes(): boolean {
|
export function isGhes(): boolean {
|
||||||
const ghUrl = new URL(
|
const ghUrl = new URL(
|
||||||
|
@ -25,6 +28,29 @@ export function isExactKeyMatch(key: string, cacheKey?: string): boolean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function deleteCacheByKey(key: string, owner: string, repo: string) {
|
||||||
|
const octokit = new Octokit();
|
||||||
|
let response;
|
||||||
|
try {
|
||||||
|
response = await octokit.rest.actions.deleteActionsCacheByKey({
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
key: key
|
||||||
|
});
|
||||||
|
if (response.status === 200) {
|
||||||
|
core.info(`Succesfully deleted cache with key: ${response.data.actions_caches[0].key}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof RequestError) {
|
||||||
|
let err = e as RequestError;
|
||||||
|
let errData = err.response?.data as any | undefined;
|
||||||
|
exports.logWarning(`${err.name} '${err.status}: ${errData?.message}' trying to delete cache with key: ${key}`);
|
||||||
|
}
|
||||||
|
response = e;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
export function logWarning(message: string): void {
|
export function logWarning(message: string): void {
|
||||||
const warningPrefix = "[warning]";
|
const warningPrefix = "[warning]";
|
||||||
core.info(`${warningPrefix}${message}`);
|
core.info(`${warningPrefix}${message}`);
|
||||||
|
|
Loading…
Add table
Reference in a new issue