mirror of https://github.com/actions/cache
Merge remote-tracking branch 'origin/700-actionscache-granular-cache-control' into kotewar/readme-updates-for-granular-control
This commit is contained in:
commit
0cc9c1d4e8
|
|
@ -27,6 +27,7 @@ jobs:
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16.x
|
node-version: 16.x
|
||||||
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Rebuild the dist/ directory
|
- name: Rebuild the dist/ directory
|
||||||
|
|
|
||||||
|
|
@ -25,17 +25,7 @@ jobs:
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16.x
|
node-version: 16.x
|
||||||
- name: Determine npm cache directory
|
cache: npm
|
||||||
id: npm-cache
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=dir::$(npm config get cache)"
|
|
||||||
- name: Restore npm cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ${{ steps.npm-cache.outputs.dir }}
|
|
||||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-node-
|
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- name: Prettier Format Check
|
- name: Prettier Format Check
|
||||||
run: npm run format-check
|
run: npm run format-check
|
||||||
|
|
|
||||||
|
|
@ -40,3 +40,9 @@
|
||||||
### 3.0.11
|
### 3.0.11
|
||||||
- Update toolkit version to 3.0.5 to include `@actions/core@^1.10.0`
|
- Update toolkit version to 3.0.5 to include `@actions/core@^1.10.0`
|
||||||
- Update `@actions/cache` to use updated `saveState` and `setOutput` functions from `@actions/core@^1.10.0`
|
- Update `@actions/cache` to use updated `saveState` and `setOutput` functions from `@actions/core@^1.10.0`
|
||||||
|
|
||||||
|
### 3.1.0-beta.1
|
||||||
|
- Update `@actions/cache` on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. ([issue](https://github.com/actions/cache/issues/984))
|
||||||
|
|
||||||
|
### 3.1.0-beta.2
|
||||||
|
- Added support for fallback to gzip to restore old caches on windows.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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 { Events, Outputs, RefKey, State } from "../src/constants";
|
import { Events, RefKey } from "../src/constants";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
|
@ -79,83 +79,6 @@ test("isExactKeyMatch with same key and different casing returns true", () => {
|
||||||
expect(actionUtils.isExactKeyMatch(key, cacheKey)).toBe(true);
|
expect(actionUtils.isExactKeyMatch(key, cacheKey)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("setOutputAndState with undefined entry to set cache-hit output", () => {
|
|
||||||
const key = "linux-rust";
|
|
||||||
const cacheKey = undefined;
|
|
||||||
|
|
||||||
const setOutputMock = jest.spyOn(core, "setOutput");
|
|
||||||
const saveStateMock = jest.spyOn(core, "saveState");
|
|
||||||
|
|
||||||
actionUtils.setOutputAndState(key, cacheKey);
|
|
||||||
|
|
||||||
expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "false");
|
|
||||||
expect(setOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
expect(saveStateMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("setOutputAndState with exact match to set cache-hit output and state", () => {
|
|
||||||
const key = "linux-rust";
|
|
||||||
const cacheKey = "linux-rust";
|
|
||||||
|
|
||||||
const setOutputMock = jest.spyOn(core, "setOutput");
|
|
||||||
const saveStateMock = jest.spyOn(core, "saveState");
|
|
||||||
|
|
||||||
actionUtils.setOutputAndState(key, cacheKey);
|
|
||||||
|
|
||||||
expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "true");
|
|
||||||
expect(setOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
expect(saveStateMock).toHaveBeenCalledWith(State.CacheMatchedKey, cacheKey);
|
|
||||||
expect(saveStateMock).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("setOutputAndState with no exact match to set cache-hit output and state", () => {
|
|
||||||
const key = "linux-rust";
|
|
||||||
const cacheKey = "linux-rust-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
|
|
||||||
const setOutputMock = jest.spyOn(core, "setOutput");
|
|
||||||
const saveStateMock = jest.spyOn(core, "saveState");
|
|
||||||
|
|
||||||
actionUtils.setOutputAndState(key, cacheKey);
|
|
||||||
|
|
||||||
expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "false");
|
|
||||||
expect(setOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
expect(saveStateMock).toHaveBeenCalledWith(State.CacheMatchedKey, cacheKey);
|
|
||||||
expect(saveStateMock).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("getCacheState with no state returns undefined", () => {
|
|
||||||
const getStateMock = jest.spyOn(core, "getState");
|
|
||||||
getStateMock.mockImplementation(() => {
|
|
||||||
return "";
|
|
||||||
});
|
|
||||||
|
|
||||||
const state = actionUtils.getCacheState();
|
|
||||||
|
|
||||||
expect(state).toBe(undefined);
|
|
||||||
|
|
||||||
expect(getStateMock).toHaveBeenCalledWith(State.CacheMatchedKey);
|
|
||||||
expect(getStateMock).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("getCacheState with valid state", () => {
|
|
||||||
const cacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
|
|
||||||
const getStateMock = jest.spyOn(core, "getState");
|
|
||||||
getStateMock.mockImplementation(() => {
|
|
||||||
return cacheKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
const state = actionUtils.getCacheState();
|
|
||||||
|
|
||||||
expect(state).toEqual(cacheKey);
|
|
||||||
|
|
||||||
expect(getStateMock).toHaveBeenCalledWith(State.CacheMatchedKey);
|
|
||||||
expect(getStateMock).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("logWarning logs a message with a warning prefix", () => {
|
test("logWarning logs a message with a warning prefix", () => {
|
||||||
const message = "A warning occurred.";
|
const message = "A warning occurred.";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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 { Events, Inputs, RefKey } from "../src/constants";
|
import { Events, RefKey } from "../src/constants";
|
||||||
import run from "../src/restore";
|
import run from "../src/restore";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
@ -45,158 +45,6 @@ afterEach(() => {
|
||||||
delete process.env[RefKey];
|
delete process.env[RefKey];
|
||||||
});
|
});
|
||||||
|
|
||||||
test("restore with invalid event outputs warning", async () => {
|
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const invalidEvent = "commit_comment";
|
|
||||||
process.env[Events.Key] = invalidEvent;
|
|
||||||
delete process.env[RefKey];
|
|
||||||
await run();
|
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
|
||||||
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
|
||||||
);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore without AC available should no-op", async () => {
|
|
||||||
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
|
|
||||||
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
|
||||||
() => false
|
|
||||||
);
|
|
||||||
|
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore on GHES without AC available should no-op", async () => {
|
|
||||||
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
|
||||||
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
|
||||||
() => false
|
|
||||||
);
|
|
||||||
|
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore on GHES with AC available ", async () => {
|
|
||||||
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
|
||||||
const path = "node_modules";
|
|
||||||
const key = "node-test";
|
|
||||||
testUtils.setInputs({
|
|
||||||
path: path,
|
|
||||||
key
|
|
||||||
});
|
|
||||||
|
|
||||||
const infoMock = jest.spyOn(core, "info");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const stateMock = jest.spyOn(core, "saveState");
|
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
|
||||||
const restoreCacheMock = jest
|
|
||||||
.spyOn(cache, "restoreCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve(key);
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
|
||||||
|
|
||||||
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledWith(true);
|
|
||||||
|
|
||||||
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore with no path should fail", async () => {
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
|
||||||
await run();
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
// this input isn't necessary for restore b/c tarball contains entries relative to workspace
|
|
||||||
expect(failedMock).not.toHaveBeenCalledWith(
|
|
||||||
"Input required and not supplied: path"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore with no key", async () => {
|
|
||||||
testUtils.setInput(Inputs.Path, "node_modules");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
|
||||||
await run();
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
expect(failedMock).toHaveBeenCalledWith(
|
|
||||||
"Input required and not supplied: key"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore with too many keys should fail", async () => {
|
|
||||||
const path = "node_modules";
|
|
||||||
const key = "node-test";
|
|
||||||
const restoreKeys = [...Array(20).keys()].map(x => x.toString());
|
|
||||||
testUtils.setInputs({
|
|
||||||
path: path,
|
|
||||||
key,
|
|
||||||
restoreKeys
|
|
||||||
});
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
|
||||||
await run();
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, restoreKeys);
|
|
||||||
expect(failedMock).toHaveBeenCalledWith(
|
|
||||||
`Key Validation Error: Keys are limited to a maximum of 10.`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore with large key should fail", async () => {
|
|
||||||
const path = "node_modules";
|
|
||||||
const key = "foo".repeat(512); // Over the 512 character limit
|
|
||||||
testUtils.setInputs({
|
|
||||||
path: path,
|
|
||||||
key
|
|
||||||
});
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
|
||||||
await run();
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
|
||||||
expect(failedMock).toHaveBeenCalledWith(
|
|
||||||
`Key Validation Error: ${key} cannot be larger than 512 characters.`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore with invalid key should fail", async () => {
|
|
||||||
const path = "node_modules";
|
|
||||||
const key = "comma,comma";
|
|
||||||
testUtils.setInputs({
|
|
||||||
path: path,
|
|
||||||
key
|
|
||||||
});
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
|
||||||
await run();
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
|
||||||
expect(failedMock).toHaveBeenCalledWith(
|
|
||||||
`Key Validation Error: ${key} cannot contain commas.`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("restore with no cache found", async () => {
|
test("restore with no cache found", async () => {
|
||||||
const path = "node_modules";
|
const path = "node_modules";
|
||||||
const key = "node-test";
|
const key = "node-test";
|
||||||
|
|
@ -270,7 +118,7 @@ test("restore with cache found for key", async () => {
|
||||||
const infoMock = jest.spyOn(core, "info");
|
const infoMock = jest.spyOn(core, "info");
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
const stateMock = jest.spyOn(core, "saveState");
|
const stateMock = jest.spyOn(core, "saveState");
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
||||||
const restoreCacheMock = jest
|
const restoreCacheMock = jest
|
||||||
.spyOn(cache, "restoreCache")
|
.spyOn(cache, "restoreCache")
|
||||||
.mockImplementationOnce(() => {
|
.mockImplementationOnce(() => {
|
||||||
|
|
@ -284,7 +132,7 @@ test("restore with cache found for key", async () => {
|
||||||
|
|
||||||
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledWith(true);
|
expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true");
|
||||||
|
|
||||||
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`);
|
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`);
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
|
@ -303,7 +151,7 @@ test("restore with cache found for restore key", async () => {
|
||||||
const infoMock = jest.spyOn(core, "info");
|
const infoMock = jest.spyOn(core, "info");
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
const stateMock = jest.spyOn(core, "saveState");
|
const stateMock = jest.spyOn(core, "saveState");
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
||||||
const restoreCacheMock = jest
|
const restoreCacheMock = jest
|
||||||
.spyOn(cache, "restoreCache")
|
.spyOn(cache, "restoreCache")
|
||||||
.mockImplementationOnce(() => {
|
.mockImplementationOnce(() => {
|
||||||
|
|
@ -317,120 +165,9 @@ test("restore with cache found for restore key", async () => {
|
||||||
|
|
||||||
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
|
expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false");
|
||||||
|
|
||||||
expect(infoMock).toHaveBeenCalledWith(
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
`Cache restored from key: ${restoreKey}`
|
`Cache restored from key: ${restoreKey}`
|
||||||
);
|
);
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("restore with enabling save on any failure feature", async () => {
|
|
||||||
const path = "node_modules";
|
|
||||||
const key = "node-test";
|
|
||||||
const restoreKey = "node-";
|
|
||||||
testUtils.setInputs({
|
|
||||||
path: path,
|
|
||||||
key,
|
|
||||||
restoreKeys: [restoreKey],
|
|
||||||
saveOnAnyFailure: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const debugMock = jest.spyOn(core, "debug");
|
|
||||||
const infoMock = jest.spyOn(core, "info");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const stateMock = jest.spyOn(core, "saveState");
|
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
|
||||||
const restoreCacheMock = jest
|
|
||||||
.spyOn(cache, "restoreCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve(restoreKey);
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
|
|
||||||
|
|
||||||
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
|
|
||||||
|
|
||||||
expect(debugMock).toHaveBeenCalledWith(
|
|
||||||
`Exporting environment variable SAVE_CACHE_ON_ANY_FAILURE`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(infoMock).toHaveBeenCalledWith(
|
|
||||||
`Input Variable SAVE_CACHE_ON_ANY_FAILURE is set to true, the cache will be saved despite of any failure in the build.`
|
|
||||||
);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Fail restore when fail on cache miss is enabled and primary key not found", async () => {
|
|
||||||
const path = "node_modules";
|
|
||||||
const key = "node-test";
|
|
||||||
const restoreKey = "node-";
|
|
||||||
testUtils.setInputs({
|
|
||||||
path: path,
|
|
||||||
key,
|
|
||||||
restoreKeys: [restoreKey],
|
|
||||||
failOnCacheMiss: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const stateMock = jest.spyOn(core, "saveState");
|
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
|
||||||
const restoreCacheMock = jest
|
|
||||||
.spyOn(cache, "restoreCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
|
|
||||||
|
|
||||||
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(0);
|
|
||||||
|
|
||||||
expect(failedMock).toHaveBeenCalledWith(
|
|
||||||
`Cache with the given input key ${key} is not found, hence exiting the workflow as the fail-on-cache-miss requirement is not met.`
|
|
||||||
);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Fail restore when fail on cache miss is enabled and primary key doesn't match restored key", async () => {
|
|
||||||
const path = "node_modules";
|
|
||||||
const key = "node-test";
|
|
||||||
const restoreKey = "node-";
|
|
||||||
testUtils.setInputs({
|
|
||||||
path: path,
|
|
||||||
key,
|
|
||||||
restoreKeys: [restoreKey],
|
|
||||||
failOnCacheMiss: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const stateMock = jest.spyOn(core, "saveState");
|
|
||||||
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
|
||||||
const restoreCacheMock = jest
|
|
||||||
.spyOn(cache, "restoreCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve(restoreKey);
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
|
|
||||||
|
|
||||||
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
|
|
||||||
|
|
||||||
expect(failedMock).toHaveBeenCalledWith(
|
|
||||||
`Restored cache key doesn't match the given input key ${key}, hence exiting the workflow as the fail-on-cache-miss requirement is not met.`
|
|
||||||
);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,326 @@
|
||||||
|
import * as cache from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Events, Inputs, RefKey } from "../src/constants";
|
||||||
|
import run from "../src/restoreImpl";
|
||||||
|
import { StateProvider } from "../src/stateProvider";
|
||||||
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
jest.mock("../src/utils/actionUtils");
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation(
|
||||||
|
(key, cacheResult) => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.isExactKeyMatch(key, cacheResult);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isValidEvent").mockImplementation(() => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.isValidEvent();
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "getInputAsArray").mockImplementation(
|
||||||
|
(name, options) => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.getInputAsArray(name, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env[Events.Key] = Events.Push;
|
||||||
|
process.env[RefKey] = "refs/heads/feature-branch";
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
testUtils.clearInputs();
|
||||||
|
delete process.env[Events.Key];
|
||||||
|
delete process.env[RefKey];
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with invalid event outputs warning", async () => {
|
||||||
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const invalidEvent = "commit_comment";
|
||||||
|
process.env[Events.Key] = invalidEvent;
|
||||||
|
delete process.env[RefKey];
|
||||||
|
await run(new StateProvider());
|
||||||
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
|
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
||||||
|
);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore without AC available should no-op", async () => {
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => false
|
||||||
|
);
|
||||||
|
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore on GHES without AC available should no-op", async () => {
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => false
|
||||||
|
);
|
||||||
|
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore on GHES with AC available ", async () => {
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const stateMock = jest.spyOn(core, "saveState");
|
||||||
|
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
||||||
|
|
||||||
|
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true");
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with no path should fail", async () => {
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
await run(new StateProvider());
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
// this input isn't necessary for restore b/c tarball contains entries relative to workspace
|
||||||
|
expect(failedMock).not.toHaveBeenCalledWith(
|
||||||
|
"Input required and not supplied: path"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with no key", async () => {
|
||||||
|
testUtils.setInput(Inputs.Path, "node_modules");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
await run(new StateProvider());
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(failedMock).toHaveBeenCalledWith(
|
||||||
|
"Input required and not supplied: key"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with too many keys should fail", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
const restoreKeys = [...Array(20).keys()].map(x => x.toString());
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key,
|
||||||
|
restoreKeys
|
||||||
|
});
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
await run(new StateProvider());
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, restoreKeys);
|
||||||
|
expect(failedMock).toHaveBeenCalledWith(
|
||||||
|
`Key Validation Error: Keys are limited to a maximum of 10.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with large key should fail", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "foo".repeat(512); // Over the 512 character limit
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key
|
||||||
|
});
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
await run(new StateProvider());
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
||||||
|
expect(failedMock).toHaveBeenCalledWith(
|
||||||
|
`Key Validation Error: ${key} cannot be larger than 512 characters.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with invalid key should fail", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "comma,comma";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key
|
||||||
|
});
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
await run(new StateProvider());
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
||||||
|
expect(failedMock).toHaveBeenCalledWith(
|
||||||
|
`Key Validation Error: ${key} cannot contain commas.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with no cache found", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const stateMock = jest.spyOn(core, "saveState");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
||||||
|
|
||||||
|
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
`Cache not found for input keys: ${key}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with restore keys and no cache found", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
const restoreKey = "node-";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key,
|
||||||
|
restoreKeys: [restoreKey]
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const stateMock = jest.spyOn(core, "saveState");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
|
||||||
|
|
||||||
|
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
`Cache not found for input keys: ${key}, ${restoreKey}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with cache found for key", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const stateMock = jest.spyOn(core, "saveState");
|
||||||
|
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
||||||
|
|
||||||
|
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true");
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with cache found for restore key", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
const restoreKey = "node-";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key,
|
||||||
|
restoreKeys: [restoreKey]
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const stateMock = jest.spyOn(core, "saveState");
|
||||||
|
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(restoreKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
|
||||||
|
|
||||||
|
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false");
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
`Cache restored from key: ${restoreKey}`
|
||||||
|
);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
import * as cache from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Events, RefKey } from "../src/constants";
|
||||||
|
import run from "../src/restoreOnly";
|
||||||
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
jest.mock("../src/utils/actionUtils");
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation(
|
||||||
|
(key, cacheResult) => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.isExactKeyMatch(key, cacheResult);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isValidEvent").mockImplementation(() => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.isValidEvent();
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "getInputAsArray").mockImplementation(
|
||||||
|
(name, options) => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.getInputAsArray(name, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env[Events.Key] = Events.Push;
|
||||||
|
process.env[RefKey] = "refs/heads/feature-branch";
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
testUtils.clearInputs();
|
||||||
|
delete process.env[Events.Key];
|
||||||
|
delete process.env[RefKey];
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with no cache found", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const outputMock = jest.spyOn(core, "setOutput");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
||||||
|
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key);
|
||||||
|
expect(outputMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
`Cache not found for input keys: ${key}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with restore keys and no cache found", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
const restoreKey = "node-";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key,
|
||||||
|
restoreKeys: [restoreKey]
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const outputMock = jest.spyOn(core, "setOutput");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
|
||||||
|
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
`Cache not found for input keys: ${key}, ${restoreKey}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with cache found for key", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const outputMock = jest.spyOn(core, "setOutput");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
|
||||||
|
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key);
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-hit", "true");
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-restore-key", key);
|
||||||
|
|
||||||
|
expect(outputMock).toHaveBeenCalledTimes(3);
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore with cache found for restore key", async () => {
|
||||||
|
const path = "node_modules";
|
||||||
|
const key = "node-test";
|
||||||
|
const restoreKey = "node-";
|
||||||
|
testUtils.setInputs({
|
||||||
|
path: path,
|
||||||
|
key,
|
||||||
|
restoreKeys: [restoreKey]
|
||||||
|
});
|
||||||
|
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const outputMock = jest.spyOn(core, "setOutput");
|
||||||
|
const restoreCacheMock = jest
|
||||||
|
.spyOn(cache, "restoreCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(restoreKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
|
||||||
|
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key);
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-hit", "false");
|
||||||
|
expect(outputMock).toHaveBeenCalledWith("cache-restore-key", restoreKey);
|
||||||
|
|
||||||
|
expect(outputMock).toHaveBeenCalledTimes(3);
|
||||||
|
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
`Cache restored from key: ${restoreKey}`
|
||||||
|
);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
@ -15,8 +15,8 @@ beforeAll(() => {
|
||||||
return jest.requireActual("@actions/core").getInput(name, options);
|
return jest.requireActual("@actions/core").getInput(name, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.spyOn(actionUtils, "getCacheState").mockImplementation(() => {
|
jest.spyOn(core, "getState").mockImplementation(name => {
|
||||||
return jest.requireActual("../src/utils/actionUtils").getCacheState();
|
return jest.requireActual("@actions/core").getState(name);
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.spyOn(actionUtils, "getInputAsArray").mockImplementation(
|
jest.spyOn(actionUtils, "getInputAsArray").mockImplementation(
|
||||||
|
|
@ -65,294 +65,6 @@ afterEach(() => {
|
||||||
delete process.env[RefKey];
|
delete process.env[RefKey];
|
||||||
});
|
});
|
||||||
|
|
||||||
test("save with invalid event outputs warning", async () => {
|
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
const invalidEvent = "commit_comment";
|
|
||||||
process.env[Events.Key] = invalidEvent;
|
|
||||||
delete process.env[RefKey];
|
|
||||||
await run();
|
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
|
||||||
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
|
||||||
);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save with no primary key in state outputs warning", async () => {
|
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
|
|
||||||
const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
jest.spyOn(core, "getState")
|
|
||||||
// Cache Entry State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return savedCacheKey;
|
|
||||||
})
|
|
||||||
// Cache Key State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return "";
|
|
||||||
});
|
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
|
||||||
`Error retrieving key from state.`
|
|
||||||
);
|
|
||||||
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save without AC available should no-op", async () => {
|
|
||||||
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
|
||||||
() => false
|
|
||||||
);
|
|
||||||
|
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save on ghes without AC available should no-op", async () => {
|
|
||||||
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
|
||||||
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
|
||||||
() => false
|
|
||||||
);
|
|
||||||
|
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save on GHES with AC available", async () => {
|
|
||||||
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
|
|
||||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
const savedCacheKey = "Linux-node-";
|
|
||||||
|
|
||||||
jest.spyOn(core, "getState")
|
|
||||||
// Cache Entry State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return savedCacheKey;
|
|
||||||
})
|
|
||||||
// Cache Key State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return primaryKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputPath = "node_modules";
|
|
||||||
testUtils.setInput(Inputs.Path, inputPath);
|
|
||||||
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
|
|
||||||
|
|
||||||
const cacheId = 4;
|
|
||||||
const saveCacheMock = jest
|
|
||||||
.spyOn(cache, "saveCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve(cacheId);
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, {
|
|
||||||
uploadChunkSize: 4000000
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save with exact match returns early", async () => {
|
|
||||||
const infoMock = jest.spyOn(core, "info");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
|
|
||||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
const savedCacheKey = primaryKey;
|
|
||||||
|
|
||||||
jest.spyOn(core, "getState")
|
|
||||||
// Cache Entry State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return savedCacheKey;
|
|
||||||
})
|
|
||||||
// Cache Key State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return primaryKey;
|
|
||||||
});
|
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
expect(infoMock).toHaveBeenCalledWith(
|
|
||||||
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
|
||||||
);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save with missing input outputs warning", async () => {
|
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
|
|
||||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
const savedCacheKey = "Linux-node-";
|
|
||||||
|
|
||||||
jest.spyOn(core, "getState")
|
|
||||||
// Cache Entry State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return savedCacheKey;
|
|
||||||
})
|
|
||||||
// Cache Key State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return primaryKey;
|
|
||||||
});
|
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
|
||||||
"Input required and not supplied: path"
|
|
||||||
);
|
|
||||||
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save with large cache outputs warning", async () => {
|
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
|
|
||||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
const savedCacheKey = "Linux-node-";
|
|
||||||
|
|
||||||
jest.spyOn(core, "getState")
|
|
||||||
// Cache Entry State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return savedCacheKey;
|
|
||||||
})
|
|
||||||
// Cache Key State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return primaryKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputPath = "node_modules";
|
|
||||||
testUtils.setInput(Inputs.Path, inputPath);
|
|
||||||
|
|
||||||
const saveCacheMock = jest
|
|
||||||
.spyOn(cache, "saveCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
throw new Error(
|
|
||||||
"Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache."
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
|
||||||
[inputPath],
|
|
||||||
primaryKey,
|
|
||||||
expect.anything()
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
|
||||||
"Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache."
|
|
||||||
);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save with reserve cache failure outputs warning", async () => {
|
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
|
|
||||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
const savedCacheKey = "Linux-node-";
|
|
||||||
|
|
||||||
jest.spyOn(core, "getState")
|
|
||||||
// Cache Entry State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return savedCacheKey;
|
|
||||||
})
|
|
||||||
// Cache Key State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return primaryKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputPath = "node_modules";
|
|
||||||
testUtils.setInput(Inputs.Path, inputPath);
|
|
||||||
|
|
||||||
const saveCacheMock = jest
|
|
||||||
.spyOn(cache, "saveCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
const actualCache = jest.requireActual("@actions/cache");
|
|
||||||
const error = new actualCache.ReserveCacheError(
|
|
||||||
`Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.`
|
|
||||||
);
|
|
||||||
throw error;
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
|
||||||
[inputPath],
|
|
||||||
primaryKey,
|
|
||||||
expect.anything()
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
|
||||||
`Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.`
|
|
||||||
);
|
|
||||||
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save with server error outputs warning", async () => {
|
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
|
||||||
|
|
||||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
|
||||||
const savedCacheKey = "Linux-node-";
|
|
||||||
|
|
||||||
jest.spyOn(core, "getState")
|
|
||||||
// Cache Entry State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return savedCacheKey;
|
|
||||||
})
|
|
||||||
// Cache Key State
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
return primaryKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputPath = "node_modules";
|
|
||||||
testUtils.setInput(Inputs.Path, inputPath);
|
|
||||||
|
|
||||||
const saveCacheMock = jest
|
|
||||||
.spyOn(cache, "saveCache")
|
|
||||||
.mockImplementationOnce(() => {
|
|
||||||
throw new Error("HTTP Error Occurred");
|
|
||||||
});
|
|
||||||
|
|
||||||
await run();
|
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
|
||||||
[inputPath],
|
|
||||||
primaryKey,
|
|
||||||
expect.anything()
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
|
||||||
expect(logWarningMock).toHaveBeenCalledWith("HTTP Error Occurred");
|
|
||||||
|
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("save with valid inputs uploads a cache", async () => {
|
test("save with valid inputs uploads a cache", async () => {
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
|
@ -362,11 +74,11 @@ test("save with valid inputs uploads a cache", async () => {
|
||||||
jest.spyOn(core, "getState")
|
jest.spyOn(core, "getState")
|
||||||
// Cache Entry State
|
// Cache Entry State
|
||||||
.mockImplementationOnce(() => {
|
.mockImplementationOnce(() => {
|
||||||
return savedCacheKey;
|
return primaryKey;
|
||||||
})
|
})
|
||||||
// Cache Key State
|
// Cache Key State
|
||||||
.mockImplementationOnce(() => {
|
.mockImplementationOnce(() => {
|
||||||
return primaryKey;
|
return savedCacheKey;
|
||||||
});
|
});
|
||||||
|
|
||||||
const inputPath = "node_modules";
|
const inputPath = "node_modules";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,386 @@
|
||||||
|
import * as cache from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Events, Inputs, RefKey } from "../src/constants";
|
||||||
|
import run from "../src/saveImpl";
|
||||||
|
import { StateProvider } from "../src/stateProvider";
|
||||||
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
jest.mock("@actions/core");
|
||||||
|
jest.mock("@actions/cache");
|
||||||
|
jest.mock("../src/utils/actionUtils");
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(core, "getInput").mockImplementation((name, options) => {
|
||||||
|
return jest.requireActual("@actions/core").getInput(name, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "getInputAsArray").mockImplementation(
|
||||||
|
(name, options) => {
|
||||||
|
return jest
|
||||||
|
.requireActual("../src/utils/actionUtils")
|
||||||
|
.getInputAsArray(name, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "getInputAsInt").mockImplementation(
|
||||||
|
(name, options) => {
|
||||||
|
return jest
|
||||||
|
.requireActual("../src/utils/actionUtils")
|
||||||
|
.getInputAsInt(name, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation(
|
||||||
|
(key, cacheResult) => {
|
||||||
|
return jest
|
||||||
|
.requireActual("../src/utils/actionUtils")
|
||||||
|
.isExactKeyMatch(key, cacheResult);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isValidEvent").mockImplementation(() => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.isValidEvent();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env[Events.Key] = Events.Push;
|
||||||
|
process.env[RefKey] = "refs/heads/feature-branch";
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
testUtils.clearInputs();
|
||||||
|
delete process.env[Events.Key];
|
||||||
|
delete process.env[RefKey];
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with invalid event outputs warning", async () => {
|
||||||
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const invalidEvent = "commit_comment";
|
||||||
|
process.env[Events.Key] = invalidEvent;
|
||||||
|
delete process.env[RefKey];
|
||||||
|
await run(new StateProvider());
|
||||||
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
|
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
||||||
|
);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with no primary key in state outputs warning", async () => {
|
||||||
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return "";
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
});
|
||||||
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(logWarningMock).toHaveBeenCalledWith(`Key is not specified.`);
|
||||||
|
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save without AC available should no-op", async () => {
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => false
|
||||||
|
);
|
||||||
|
|
||||||
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save on ghes without AC available should no-op", async () => {
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => false
|
||||||
|
);
|
||||||
|
|
||||||
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save on GHES with AC available", async () => {
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true);
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = "Linux-node-";
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputPath = "node_modules";
|
||||||
|
testUtils.setInput(Inputs.Path, inputPath);
|
||||||
|
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
|
||||||
|
|
||||||
|
const cacheId = 4;
|
||||||
|
const saveCacheMock = jest
|
||||||
|
.spyOn(cache, "saveCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(cacheId);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, {
|
||||||
|
uploadChunkSize: 4000000
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with exact match returns early", async () => {
|
||||||
|
const infoMock = jest.spyOn(core, "info");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = primaryKey;
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
||||||
|
);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with missing input outputs warning", async () => {
|
||||||
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = "Linux-node-";
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
|
"Input required and not supplied: path"
|
||||||
|
);
|
||||||
|
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with large cache outputs warning", async () => {
|
||||||
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = "Linux-node-";
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputPath = "node_modules";
|
||||||
|
testUtils.setInput(Inputs.Path, inputPath);
|
||||||
|
|
||||||
|
const saveCacheMock = jest
|
||||||
|
.spyOn(cache, "saveCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new Error(
|
||||||
|
"Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
[inputPath],
|
||||||
|
primaryKey,
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
|
"Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache."
|
||||||
|
);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with reserve cache failure outputs warning", async () => {
|
||||||
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = "Linux-node-";
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputPath = "node_modules";
|
||||||
|
testUtils.setInput(Inputs.Path, inputPath);
|
||||||
|
|
||||||
|
const saveCacheMock = jest
|
||||||
|
.spyOn(cache, "saveCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
const actualCache = jest.requireActual("@actions/cache");
|
||||||
|
const error = new actualCache.ReserveCacheError(
|
||||||
|
`Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.`
|
||||||
|
);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
[inputPath],
|
||||||
|
primaryKey,
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
|
`Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.`
|
||||||
|
);
|
||||||
|
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with server error outputs warning", async () => {
|
||||||
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = "Linux-node-";
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputPath = "node_modules";
|
||||||
|
testUtils.setInput(Inputs.Path, inputPath);
|
||||||
|
|
||||||
|
const saveCacheMock = jest
|
||||||
|
.spyOn(cache, "saveCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new Error("HTTP Error Occurred");
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
[inputPath],
|
||||||
|
primaryKey,
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(logWarningMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(logWarningMock).toHaveBeenCalledWith("HTTP Error Occurred");
|
||||||
|
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with valid inputs uploads a cache", async () => {
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = "Linux-node-";
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputPath = "node_modules";
|
||||||
|
testUtils.setInput(Inputs.Path, inputPath);
|
||||||
|
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
|
||||||
|
|
||||||
|
const cacheId = 4;
|
||||||
|
const saveCacheMock = jest
|
||||||
|
.spyOn(cache, "saveCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(cacheId);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run(new StateProvider());
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, {
|
||||||
|
uploadChunkSize: 4000000
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
import * as cache from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Events, Inputs, RefKey } from "../src/constants";
|
||||||
|
import run from "../src/saveOnly";
|
||||||
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
jest.mock("@actions/core");
|
||||||
|
jest.mock("@actions/cache");
|
||||||
|
jest.mock("../src/utils/actionUtils");
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(core, "getInput").mockImplementation((name, options) => {
|
||||||
|
return jest.requireActual("@actions/core").getInput(name, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(core, "setOutput").mockImplementation((key, value) => {
|
||||||
|
return jest.requireActual("@actions/core").getInput(key, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "getInputAsArray").mockImplementation(
|
||||||
|
(name, options) => {
|
||||||
|
return jest
|
||||||
|
.requireActual("../src/utils/actionUtils")
|
||||||
|
.getInputAsArray(name, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "getInputAsInt").mockImplementation(
|
||||||
|
(name, options) => {
|
||||||
|
return jest
|
||||||
|
.requireActual("../src/utils/actionUtils")
|
||||||
|
.getInputAsInt(name, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation(
|
||||||
|
(key, cacheResult) => {
|
||||||
|
return jest
|
||||||
|
.requireActual("../src/utils/actionUtils")
|
||||||
|
.isExactKeyMatch(key, cacheResult);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isValidEvent").mockImplementation(() => {
|
||||||
|
const actualUtils = jest.requireActual("../src/utils/actionUtils");
|
||||||
|
return actualUtils.isValidEvent();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env[Events.Key] = Events.Push;
|
||||||
|
process.env[RefKey] = "refs/heads/feature-branch";
|
||||||
|
|
||||||
|
jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
|
||||||
|
jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
|
||||||
|
() => true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
testUtils.clearInputs();
|
||||||
|
delete process.env[Events.Key];
|
||||||
|
delete process.env[RefKey];
|
||||||
|
});
|
||||||
|
|
||||||
|
test("save with valid inputs uploads a cache", async () => {
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
|
||||||
|
const inputPath = "node_modules";
|
||||||
|
testUtils.setInput(Inputs.Key, primaryKey);
|
||||||
|
testUtils.setInput(Inputs.Path, inputPath);
|
||||||
|
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
|
||||||
|
|
||||||
|
const cacheId = 4;
|
||||||
|
const saveCacheMock = jest
|
||||||
|
.spyOn(cache, "saveCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(cacheId);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, {
|
||||||
|
uploadChunkSize: 4000000
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Events, RefKey, State } from "../src/constants";
|
||||||
|
import {
|
||||||
|
IStateProvider,
|
||||||
|
NullStateProvider,
|
||||||
|
StateProvider
|
||||||
|
} from "../src/stateProvider";
|
||||||
|
|
||||||
|
jest.mock("@actions/core");
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(core, "getInput").mockImplementation((name, options) => {
|
||||||
|
return jest.requireActual("@actions/core").getInput(name, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(core, "setOutput").mockImplementation((key, value) => {
|
||||||
|
return jest.requireActual("@actions/core").setOutput(key, value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
delete process.env[Events.Key];
|
||||||
|
delete process.env[RefKey];
|
||||||
|
});
|
||||||
|
|
||||||
|
test("StateProvider saves states", async () => {
|
||||||
|
const getStateMock = jest
|
||||||
|
.spyOn(core, "getState")
|
||||||
|
.mockImplementation(name =>
|
||||||
|
jest.requireActual("@actions/core").getState(name)
|
||||||
|
);
|
||||||
|
const saveStateMock = jest
|
||||||
|
.spyOn(core, "saveState")
|
||||||
|
.mockImplementation((key, value) => {
|
||||||
|
return jest.requireActual("@actions/core").saveState(key, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const cacheMatchedKey = "node-cache";
|
||||||
|
|
||||||
|
const stateProvider: IStateProvider = new StateProvider();
|
||||||
|
stateProvider.setState("stateKey", "stateValue");
|
||||||
|
stateProvider.setState(State.CacheMatchedKey, cacheMatchedKey);
|
||||||
|
stateProvider.getState("stateKey");
|
||||||
|
stateProvider.getCacheState();
|
||||||
|
|
||||||
|
expect(getStateMock).toHaveBeenCalledTimes(2);
|
||||||
|
expect(saveStateMock).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("NullStateProvider saves outputs", async () => {
|
||||||
|
const getStateMock = jest
|
||||||
|
.spyOn(core, "getState")
|
||||||
|
.mockImplementation(name =>
|
||||||
|
jest.requireActual("@actions/core").getState(name)
|
||||||
|
);
|
||||||
|
const setOutputMock = jest
|
||||||
|
.spyOn(core, "setOutput")
|
||||||
|
.mockImplementation((key, value) => {
|
||||||
|
return jest.requireActual("@actions/core").setOutput(key, value);
|
||||||
|
});
|
||||||
|
const cacheMatchedKey = "node-cache";
|
||||||
|
const nullStateProvider: IStateProvider = new NullStateProvider();
|
||||||
|
nullStateProvider.setState(State.CacheMatchedKey, "outputValue");
|
||||||
|
nullStateProvider.setState(State.CachePrimaryKey, cacheMatchedKey);
|
||||||
|
nullStateProvider.getState("outputKey");
|
||||||
|
nullStateProvider.getCacheState();
|
||||||
|
|
||||||
|
expect(getStateMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(setOutputMock).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
10
action.yml
10
action.yml
|
|
@ -14,14 +14,6 @@ inputs:
|
||||||
upload-chunk-size:
|
upload-chunk-size:
|
||||||
description: 'The chunk size used to split up large files during upload, in bytes'
|
description: 'The chunk size used to split up large files during upload, in bytes'
|
||||||
required: false
|
required: false
|
||||||
exit-on-cache-miss:
|
|
||||||
description: 'Fail the workflow if the cache is not found for the primary key'
|
|
||||||
required: false
|
|
||||||
default: false
|
|
||||||
save-on-any-failure:
|
|
||||||
description: 'Save cache (on cache miss) despite of any failure during the workflow run'
|
|
||||||
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'
|
||||||
|
|
@ -29,7 +21,7 @@ runs:
|
||||||
using: 'node16'
|
using: 'node16'
|
||||||
main: 'dist/restore/index.js'
|
main: 'dist/restore/index.js'
|
||||||
post: 'dist/save/index.js'
|
post: 'dist/save/index.js'
|
||||||
post-if: (success() || (env.SAVE_CACHE_ON_ANY_FAILURE == 'yes'))
|
post-if: success()
|
||||||
branding:
|
branding:
|
||||||
icon: 'archive'
|
icon: 'archive'
|
||||||
color: 'gray-dark'
|
color: 'gray-dark'
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1177,10 +1177,6 @@ function getVersion(app) {
|
||||||
// Use zstandard if possible to maximize cache performance
|
// Use zstandard if possible to maximize cache performance
|
||||||
function getCompressionMethod() {
|
function getCompressionMethod() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (process.platform === 'win32' && !(yield isGnuTarInstalled())) {
|
|
||||||
// Disable zstd due to bug https://github.com/actions/cache/issues/301
|
|
||||||
return constants_1.CompressionMethod.Gzip;
|
|
||||||
}
|
|
||||||
const versionOutput = yield getVersion('zstd');
|
const versionOutput = yield getVersion('zstd');
|
||||||
const version = semver.clean(versionOutput);
|
const version = semver.clean(versionOutput);
|
||||||
if (!versionOutput.toLowerCase().includes('zstd command line interface')) {
|
if (!versionOutput.toLowerCase().includes('zstd command line interface')) {
|
||||||
|
|
@ -1204,13 +1200,16 @@ function getCacheFileName(compressionMethod) {
|
||||||
: constants_1.CacheFilename.Zstd;
|
: constants_1.CacheFilename.Zstd;
|
||||||
}
|
}
|
||||||
exports.getCacheFileName = getCacheFileName;
|
exports.getCacheFileName = getCacheFileName;
|
||||||
function isGnuTarInstalled() {
|
function getGnuTarPathOnWindows() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (fs.existsSync(constants_1.GnuTarPathOnWindows)) {
|
||||||
|
return constants_1.GnuTarPathOnWindows;
|
||||||
|
}
|
||||||
const versionOutput = yield getVersion('tar');
|
const versionOutput = yield getVersion('tar');
|
||||||
return versionOutput.toLowerCase().includes('gnu tar');
|
return versionOutput.toLowerCase().includes('gnu tar') ? io.which('tar') : '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.isGnuTarInstalled = isGnuTarInstalled;
|
exports.getGnuTarPathOnWindows = getGnuTarPathOnWindows;
|
||||||
function assertDefined(name, value) {
|
function assertDefined(name, value) {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
throw Error(`Expected ${name} but value was undefiend`);
|
throw Error(`Expected ${name} but value was undefiend`);
|
||||||
|
|
@ -3046,19 +3045,18 @@ exports.default = _default;
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 105 */,
|
/* 105 */,
|
||||||
/* 106 */
|
/* 106 */
|
||||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
/***/ (function(__unusedmodule, exports) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', { value: true });
|
Object.defineProperty(exports, '__esModule', { value: true });
|
||||||
|
|
||||||
var tslib = __webpack_require__(640);
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
var listenersMap = new WeakMap();
|
/// <reference path="../shims-public.d.ts" />
|
||||||
var abortedMap = new WeakMap();
|
const listenersMap = new WeakMap();
|
||||||
|
const abortedMap = new WeakMap();
|
||||||
/**
|
/**
|
||||||
* An aborter instance implements AbortSignal interface, can abort HTTP requests.
|
* An aborter instance implements AbortSignal interface, can abort HTTP requests.
|
||||||
*
|
*
|
||||||
|
|
@ -3072,8 +3070,8 @@ var abortedMap = new WeakMap();
|
||||||
* await doAsyncWork(AbortSignal.none);
|
* await doAsyncWork(AbortSignal.none);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
var AbortSignal = /** @class */ (function () {
|
class AbortSignal {
|
||||||
function AbortSignal() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
* onabort event listener.
|
* onabort event listener.
|
||||||
*/
|
*/
|
||||||
|
|
@ -3081,74 +3079,65 @@ var AbortSignal = /** @class */ (function () {
|
||||||
listenersMap.set(this, []);
|
listenersMap.set(this, []);
|
||||||
abortedMap.set(this, false);
|
abortedMap.set(this, false);
|
||||||
}
|
}
|
||||||
Object.defineProperty(AbortSignal.prototype, "aborted", {
|
/**
|
||||||
/**
|
* Status of whether aborted or not.
|
||||||
* Status of whether aborted or not.
|
*
|
||||||
*
|
* @readonly
|
||||||
* @readonly
|
*/
|
||||||
*/
|
get aborted() {
|
||||||
get: function () {
|
if (!abortedMap.has(this)) {
|
||||||
if (!abortedMap.has(this)) {
|
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
||||||
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
}
|
||||||
}
|
return abortedMap.get(this);
|
||||||
return abortedMap.get(this);
|
}
|
||||||
},
|
/**
|
||||||
enumerable: false,
|
* Creates a new AbortSignal instance that will never be aborted.
|
||||||
configurable: true
|
*
|
||||||
});
|
* @readonly
|
||||||
Object.defineProperty(AbortSignal, "none", {
|
*/
|
||||||
/**
|
static get none() {
|
||||||
* Creates a new AbortSignal instance that will never be aborted.
|
return new AbortSignal();
|
||||||
*
|
}
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
get: function () {
|
|
||||||
return new AbortSignal();
|
|
||||||
},
|
|
||||||
enumerable: false,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* Added new "abort" event listener, only support "abort" event.
|
* Added new "abort" event listener, only support "abort" event.
|
||||||
*
|
*
|
||||||
* @param _type - Only support "abort" event
|
* @param _type - Only support "abort" event
|
||||||
* @param listener - The listener to be added
|
* @param listener - The listener to be added
|
||||||
*/
|
*/
|
||||||
AbortSignal.prototype.addEventListener = function (
|
addEventListener(
|
||||||
// tslint:disable-next-line:variable-name
|
// tslint:disable-next-line:variable-name
|
||||||
_type, listener) {
|
_type, listener) {
|
||||||
if (!listenersMap.has(this)) {
|
if (!listenersMap.has(this)) {
|
||||||
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
||||||
}
|
}
|
||||||
var listeners = listenersMap.get(this);
|
const listeners = listenersMap.get(this);
|
||||||
listeners.push(listener);
|
listeners.push(listener);
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* Remove "abort" event listener, only support "abort" event.
|
* Remove "abort" event listener, only support "abort" event.
|
||||||
*
|
*
|
||||||
* @param _type - Only support "abort" event
|
* @param _type - Only support "abort" event
|
||||||
* @param listener - The listener to be removed
|
* @param listener - The listener to be removed
|
||||||
*/
|
*/
|
||||||
AbortSignal.prototype.removeEventListener = function (
|
removeEventListener(
|
||||||
// tslint:disable-next-line:variable-name
|
// tslint:disable-next-line:variable-name
|
||||||
_type, listener) {
|
_type, listener) {
|
||||||
if (!listenersMap.has(this)) {
|
if (!listenersMap.has(this)) {
|
||||||
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
||||||
}
|
}
|
||||||
var listeners = listenersMap.get(this);
|
const listeners = listenersMap.get(this);
|
||||||
var index = listeners.indexOf(listener);
|
const index = listeners.indexOf(listener);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
listeners.splice(index, 1);
|
listeners.splice(index, 1);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* Dispatches a synthetic event to the AbortSignal.
|
* Dispatches a synthetic event to the AbortSignal.
|
||||||
*/
|
*/
|
||||||
AbortSignal.prototype.dispatchEvent = function (_event) {
|
dispatchEvent(_event) {
|
||||||
throw new Error("This is a stub dispatchEvent implementation that should not be used. It only exists for type-checking purposes.");
|
throw new Error("This is a stub dispatchEvent implementation that should not be used. It only exists for type-checking purposes.");
|
||||||
};
|
}
|
||||||
return AbortSignal;
|
}
|
||||||
}());
|
|
||||||
/**
|
/**
|
||||||
* Helper to trigger an abort event immediately, the onabort and all abort event listeners will be triggered.
|
* Helper to trigger an abort event immediately, the onabort and all abort event listeners will be triggered.
|
||||||
* Will try to trigger abort event for all linked AbortSignal nodes.
|
* Will try to trigger abort event for all linked AbortSignal nodes.
|
||||||
|
|
@ -3166,12 +3155,12 @@ function abortSignal(signal) {
|
||||||
if (signal.onabort) {
|
if (signal.onabort) {
|
||||||
signal.onabort.call(signal);
|
signal.onabort.call(signal);
|
||||||
}
|
}
|
||||||
var listeners = listenersMap.get(signal);
|
const listeners = listenersMap.get(signal);
|
||||||
if (listeners) {
|
if (listeners) {
|
||||||
// Create a copy of listeners so mutations to the array
|
// Create a copy of listeners so mutations to the array
|
||||||
// (e.g. via removeListener calls) don't affect the listeners
|
// (e.g. via removeListener calls) don't affect the listeners
|
||||||
// we invoke.
|
// we invoke.
|
||||||
listeners.slice().forEach(function (listener) {
|
listeners.slice().forEach((listener) => {
|
||||||
listener.call(signal, { type: "abort" });
|
listener.call(signal, { type: "abort" });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -3197,15 +3186,12 @@ function abortSignal(signal) {
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
var AbortError = /** @class */ (function (_super) {
|
class AbortError extends Error {
|
||||||
tslib.__extends(AbortError, _super);
|
constructor(message) {
|
||||||
function AbortError(message) {
|
super(message);
|
||||||
var _this = _super.call(this, message) || this;
|
this.name = "AbortError";
|
||||||
_this.name = "AbortError";
|
|
||||||
return _this;
|
|
||||||
}
|
}
|
||||||
return AbortError;
|
}
|
||||||
}(Error));
|
|
||||||
/**
|
/**
|
||||||
* An AbortController provides an AbortSignal and the associated controls to signal
|
* An AbortController provides an AbortSignal and the associated controls to signal
|
||||||
* that an asynchronous operation should be aborted.
|
* that an asynchronous operation should be aborted.
|
||||||
|
|
@ -3240,10 +3226,9 @@ var AbortError = /** @class */ (function (_super) {
|
||||||
* await doAsyncWork(aborter.withTimeout(25 * 1000));
|
* await doAsyncWork(aborter.withTimeout(25 * 1000));
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
var AbortController = /** @class */ (function () {
|
class AbortController {
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
function AbortController(parentSignals) {
|
constructor(parentSignals) {
|
||||||
var _this = this;
|
|
||||||
this._signal = new AbortSignal();
|
this._signal = new AbortSignal();
|
||||||
if (!parentSignals) {
|
if (!parentSignals) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -3253,8 +3238,7 @@ var AbortController = /** @class */ (function () {
|
||||||
// eslint-disable-next-line prefer-rest-params
|
// eslint-disable-next-line prefer-rest-params
|
||||||
parentSignals = arguments;
|
parentSignals = arguments;
|
||||||
}
|
}
|
||||||
for (var _i = 0, parentSignals_1 = parentSignals; _i < parentSignals_1.length; _i++) {
|
for (const parentSignal of parentSignals) {
|
||||||
var parentSignal = parentSignals_1[_i];
|
|
||||||
// if the parent signal has already had abort() called,
|
// if the parent signal has already had abort() called,
|
||||||
// then call abort on this signal as well.
|
// then call abort on this signal as well.
|
||||||
if (parentSignal.aborted) {
|
if (parentSignal.aborted) {
|
||||||
|
|
@ -3262,47 +3246,42 @@ var AbortController = /** @class */ (function () {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// when the parent signal aborts, this signal should as well.
|
// when the parent signal aborts, this signal should as well.
|
||||||
parentSignal.addEventListener("abort", function () {
|
parentSignal.addEventListener("abort", () => {
|
||||||
_this.abort();
|
this.abort();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object.defineProperty(AbortController.prototype, "signal", {
|
/**
|
||||||
/**
|
* The AbortSignal associated with this controller that will signal aborted
|
||||||
* The AbortSignal associated with this controller that will signal aborted
|
* when the abort method is called on this controller.
|
||||||
* when the abort method is called on this controller.
|
*
|
||||||
*
|
* @readonly
|
||||||
* @readonly
|
*/
|
||||||
*/
|
get signal() {
|
||||||
get: function () {
|
return this._signal;
|
||||||
return this._signal;
|
}
|
||||||
},
|
|
||||||
enumerable: false,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* Signal that any operations passed this controller's associated abort signal
|
* Signal that any operations passed this controller's associated abort signal
|
||||||
* to cancel any remaining work and throw an `AbortError`.
|
* to cancel any remaining work and throw an `AbortError`.
|
||||||
*/
|
*/
|
||||||
AbortController.prototype.abort = function () {
|
abort() {
|
||||||
abortSignal(this._signal);
|
abortSignal(this._signal);
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* Creates a new AbortSignal instance that will abort after the provided ms.
|
* Creates a new AbortSignal instance that will abort after the provided ms.
|
||||||
* @param ms - Elapsed time in milliseconds to trigger an abort.
|
* @param ms - Elapsed time in milliseconds to trigger an abort.
|
||||||
*/
|
*/
|
||||||
AbortController.timeout = function (ms) {
|
static timeout(ms) {
|
||||||
var signal = new AbortSignal();
|
const signal = new AbortSignal();
|
||||||
var timer = setTimeout(abortSignal, ms, signal);
|
const timer = setTimeout(abortSignal, ms, signal);
|
||||||
// Prevent the active Timer from keeping the Node.js event loop active.
|
// Prevent the active Timer from keeping the Node.js event loop active.
|
||||||
if (typeof timer.unref === "function") {
|
if (typeof timer.unref === "function") {
|
||||||
timer.unref();
|
timer.unref();
|
||||||
}
|
}
|
||||||
return signal;
|
return signal;
|
||||||
};
|
}
|
||||||
return AbortController;
|
}
|
||||||
}());
|
|
||||||
|
|
||||||
exports.AbortController = AbortController;
|
exports.AbortController = AbortController;
|
||||||
exports.AbortError = AbortError;
|
exports.AbortError = AbortError;
|
||||||
|
|
@ -3402,7 +3381,7 @@ const http_client_1 = __webpack_require__(425);
|
||||||
const auth_1 = __webpack_require__(554);
|
const auth_1 = __webpack_require__(554);
|
||||||
const crypto = __importStar(__webpack_require__(417));
|
const crypto = __importStar(__webpack_require__(417));
|
||||||
const fs = __importStar(__webpack_require__(747));
|
const fs = __importStar(__webpack_require__(747));
|
||||||
const url_1 = __webpack_require__(835);
|
const url_1 = __webpack_require__(414);
|
||||||
const utils = __importStar(__webpack_require__(15));
|
const utils = __importStar(__webpack_require__(15));
|
||||||
const constants_1 = __webpack_require__(931);
|
const constants_1 = __webpack_require__(931);
|
||||||
const downloadUtils_1 = __webpack_require__(251);
|
const downloadUtils_1 = __webpack_require__(251);
|
||||||
|
|
@ -4964,19 +4943,19 @@ exports.checkBypass = checkBypass;
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.RefKey = exports.Variables = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0;
|
exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0;
|
||||||
var Inputs;
|
var Inputs;
|
||||||
(function (Inputs) {
|
(function (Inputs) {
|
||||||
Inputs["Key"] = "key";
|
Inputs["Key"] = "key";
|
||||||
Inputs["Path"] = "path";
|
Inputs["Path"] = "path";
|
||||||
Inputs["RestoreKeys"] = "restore-keys";
|
Inputs["RestoreKeys"] = "restore-keys";
|
||||||
Inputs["UploadChunkSize"] = "upload-chunk-size";
|
Inputs["UploadChunkSize"] = "upload-chunk-size"; // Input for cache, save action
|
||||||
Inputs["FailOnCacheMiss"] = "fail-on-cache-miss";
|
|
||||||
Inputs["SaveOnAnyFailure"] = "save-on-any-failure";
|
|
||||||
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
||||||
var Outputs;
|
var Outputs;
|
||||||
(function (Outputs) {
|
(function (Outputs) {
|
||||||
Outputs["CacheHit"] = "cache-hit";
|
Outputs["CacheHit"] = "cache-hit";
|
||||||
|
Outputs["CachePrimaryKey"] = "cache-primary-key";
|
||||||
|
Outputs["CacheRestoreKey"] = "cache-restore-key"; // Output from restore action
|
||||||
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
||||||
var State;
|
var State;
|
||||||
(function (State) {
|
(function (State) {
|
||||||
|
|
@ -4989,10 +4968,6 @@ var Events;
|
||||||
Events["Push"] = "push";
|
Events["Push"] = "push";
|
||||||
Events["PullRequest"] = "pull_request";
|
Events["PullRequest"] = "pull_request";
|
||||||
})(Events = exports.Events || (exports.Events = {}));
|
})(Events = exports.Events || (exports.Events = {}));
|
||||||
var Variables;
|
|
||||||
(function (Variables) {
|
|
||||||
Variables["SaveCacheOnAnyFailure"] = "SAVE_CACHE_ON_ANY_FAILURE";
|
|
||||||
})(Variables = exports.Variables || (exports.Variables = {}));
|
|
||||||
exports.RefKey = "GITHUB_REF";
|
exports.RefKey = "GITHUB_REF";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -9350,7 +9325,80 @@ function expand(str, isTop) {
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 307 */,
|
/* 307 */,
|
||||||
/* 308 */,
|
/* 308 */,
|
||||||
/* 309 */,
|
/* 309 */
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.NullStateProvider = exports.StateProvider = void 0;
|
||||||
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
const constants_1 = __webpack_require__(196);
|
||||||
|
class StateProviderBase {
|
||||||
|
constructor() {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
||||||
|
this.setState = (key, value) => { };
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
this.getState = (key) => "";
|
||||||
|
}
|
||||||
|
getCacheState() {
|
||||||
|
const cacheKey = this.getState(constants_1.State.CacheMatchedKey);
|
||||||
|
if (cacheKey) {
|
||||||
|
core.debug(`Cache state/key: ${cacheKey}`);
|
||||||
|
return cacheKey;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class StateProvider extends StateProviderBase {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
this.setState = core.saveState;
|
||||||
|
this.getState = core.getState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.StateProvider = StateProvider;
|
||||||
|
class NullStateProvider extends StateProviderBase {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
this.stateToOutputMap = new Map([
|
||||||
|
[constants_1.State.CacheMatchedKey, constants_1.Outputs.CacheRestoreKey],
|
||||||
|
[constants_1.State.CachePrimaryKey, constants_1.Outputs.CachePrimaryKey]
|
||||||
|
]);
|
||||||
|
this.setState = (key, value) => {
|
||||||
|
core.setOutput(this.stateToOutputMap.get(key), value);
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
this.getState = (key) => "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.NullStateProvider = NullStateProvider;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
/* 310 */,
|
/* 310 */,
|
||||||
/* 311 */,
|
/* 311 */,
|
||||||
/* 312 */
|
/* 312 */
|
||||||
|
|
@ -35024,7 +35072,7 @@ exports.Path = Path;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const punycode = __webpack_require__(815);
|
const punycode = __webpack_require__(815);
|
||||||
const urlParse = __webpack_require__(835).parse;
|
const urlParse = __webpack_require__(414).parse;
|
||||||
const util = __webpack_require__(669);
|
const util = __webpack_require__(669);
|
||||||
const pubsuffix = __webpack_require__(562);
|
const pubsuffix = __webpack_require__(562);
|
||||||
const Store = __webpack_require__(338).Store;
|
const Store = __webpack_require__(338).Store;
|
||||||
|
|
@ -36819,7 +36867,12 @@ module.exports = __webpack_require__(141);
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 414 */,
|
/* 414 */
|
||||||
|
/***/ (function(module) {
|
||||||
|
|
||||||
|
module.exports = require("url");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
/* 415 */,
|
/* 415 */,
|
||||||
/* 416 */,
|
/* 416 */,
|
||||||
/* 417 */
|
/* 417 */
|
||||||
|
|
@ -38061,21 +38114,19 @@ const path = __importStar(__webpack_require__(622));
|
||||||
const utils = __importStar(__webpack_require__(15));
|
const utils = __importStar(__webpack_require__(15));
|
||||||
const constants_1 = __webpack_require__(931);
|
const constants_1 = __webpack_require__(931);
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
function getTarPath(args, compressionMethod) {
|
// Function also mutates the args array. For non-mutation call with passing an empty array.
|
||||||
|
function getTarPath() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case 'win32': {
|
case 'win32': {
|
||||||
const systemTar = `${process.env['windir']}\\System32\\tar.exe`;
|
const gnuTar = yield utils.getGnuTarPathOnWindows();
|
||||||
if (compressionMethod !== constants_1.CompressionMethod.Gzip) {
|
const systemTar = constants_1.SystemTarPathOnWindows;
|
||||||
// We only use zstandard compression on windows when gnu tar is installed due to
|
if (gnuTar) {
|
||||||
// a bug with compressing large files with bsdtar + zstd
|
// Use GNUtar as default on windows
|
||||||
args.push('--force-local');
|
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
|
||||||
}
|
}
|
||||||
else if (fs_1.existsSync(systemTar)) {
|
else if (fs_1.existsSync(systemTar)) {
|
||||||
return systemTar;
|
return { path: systemTar, type: constants_1.ArchiveToolType.BSD };
|
||||||
}
|
|
||||||
else if (yield utils.isGnuTarInstalled()) {
|
|
||||||
args.push('--force-local');
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -38083,24 +38134,83 @@ function getTarPath(args, compressionMethod) {
|
||||||
const gnuTar = yield io.which('gtar', false);
|
const gnuTar = yield io.which('gtar', false);
|
||||||
if (gnuTar) {
|
if (gnuTar) {
|
||||||
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
|
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
|
||||||
args.push('--delay-directory-restore');
|
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
|
||||||
return gnuTar;
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
path: yield io.which('tar', true),
|
||||||
|
type: constants_1.ArchiveToolType.BSD
|
||||||
|
};
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return yield io.which('tar', true);
|
return {
|
||||||
|
path: yield io.which('tar', true),
|
||||||
|
type: constants_1.ArchiveToolType.GNU
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function execTar(args, compressionMethod, cwd) {
|
// Return arguments for tar as per tarPath, compressionMethod, method type and os
|
||||||
|
function getTarArgs(tarPath, compressionMethod, type, archivePath = '') {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
const args = [`"${tarPath.path}"`];
|
||||||
yield exec_1.exec(`"${yield getTarPath(args, compressionMethod)}"`, args, { cwd });
|
const cacheFileName = utils.getCacheFileName(compressionMethod);
|
||||||
|
const tarFile = 'cache.tar';
|
||||||
|
const workingDirectory = getWorkingDirectory();
|
||||||
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
|
IS_WINDOWS;
|
||||||
|
// Method specific args
|
||||||
|
switch (type) {
|
||||||
|
case 'create':
|
||||||
|
args.push('--posix', '-cf', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--exclude', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--files-from', constants_1.ManifestFilename);
|
||||||
|
break;
|
||||||
|
case 'extract':
|
||||||
|
args.push('-xf', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'));
|
||||||
|
break;
|
||||||
|
case 'list':
|
||||||
|
args.push('-tf', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
catch (error) {
|
// Platform specific args
|
||||||
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
if (tarPath.type === constants_1.ArchiveToolType.GNU) {
|
||||||
|
switch (process.platform) {
|
||||||
|
case 'win32':
|
||||||
|
args.push('--force-local');
|
||||||
|
break;
|
||||||
|
case 'darwin':
|
||||||
|
args.push('--delay-directory-restore');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getArgs(compressionMethod, type, archivePath = '') {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const tarPath = yield getTarPath();
|
||||||
|
const tarArgs = yield getTarArgs(tarPath, compressionMethod, type, archivePath);
|
||||||
|
const compressionArgs = type !== 'create'
|
||||||
|
? yield getDecompressionProgram(tarPath, compressionMethod, archivePath)
|
||||||
|
: yield getCompressionProgram(tarPath, compressionMethod);
|
||||||
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
|
IS_WINDOWS;
|
||||||
|
if (BSD_TAR_ZSTD && type !== 'create') {
|
||||||
|
return [...compressionArgs, ...tarArgs].join(' ');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return [...tarArgs, ...compressionArgs].join(' ');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -38109,32 +38219,89 @@ function getWorkingDirectory() {
|
||||||
return (_a = process.env['GITHUB_WORKSPACE']) !== null && _a !== void 0 ? _a : process.cwd();
|
return (_a = process.env['GITHUB_WORKSPACE']) !== null && _a !== void 0 ? _a : process.cwd();
|
||||||
}
|
}
|
||||||
// Common function for extractTar and listTar to get the compression method
|
// Common function for extractTar and listTar to get the compression method
|
||||||
function getCompressionProgram(compressionMethod) {
|
function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
|
||||||
// -d: Decompress.
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// unzstd is equivalent to 'zstd -d'
|
// -d: Decompress.
|
||||||
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
// unzstd is equivalent to 'zstd -d'
|
||||||
// Using 30 here because we also support 32-bit self-hosted runners.
|
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
||||||
switch (compressionMethod) {
|
// Using 30 here because we also support 32-bit self-hosted runners.
|
||||||
case constants_1.CompressionMethod.Zstd:
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
return [
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
'--use-compress-program',
|
IS_WINDOWS;
|
||||||
IS_WINDOWS ? 'zstd -d --long=30' : 'unzstd --long=30'
|
switch (compressionMethod) {
|
||||||
];
|
case constants_1.CompressionMethod.Zstd:
|
||||||
case constants_1.CompressionMethod.ZstdWithoutLong:
|
return BSD_TAR_ZSTD
|
||||||
return ['--use-compress-program', IS_WINDOWS ? 'zstd -d' : 'unzstd'];
|
? [
|
||||||
default:
|
'zstd -d --long=30 -o',
|
||||||
return ['-z'];
|
constants_1.TarFilename,
|
||||||
}
|
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
'&&'
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
'--use-compress-program',
|
||||||
|
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
|
||||||
|
];
|
||||||
|
case constants_1.CompressionMethod.ZstdWithoutLong:
|
||||||
|
return BSD_TAR_ZSTD
|
||||||
|
? [
|
||||||
|
'zstd -d -o',
|
||||||
|
constants_1.TarFilename,
|
||||||
|
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
'&&'
|
||||||
|
]
|
||||||
|
: ['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd'];
|
||||||
|
default:
|
||||||
|
return ['-z'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
|
||||||
|
// zstdmt is equivalent to 'zstd -T0'
|
||||||
|
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
||||||
|
// Using 30 here because we also support 32-bit self-hosted runners.
|
||||||
|
// Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
|
||||||
|
function getCompressionProgram(tarPath, compressionMethod) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const cacheFileName = utils.getCacheFileName(compressionMethod);
|
||||||
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
|
IS_WINDOWS;
|
||||||
|
switch (compressionMethod) {
|
||||||
|
case constants_1.CompressionMethod.Zstd:
|
||||||
|
return BSD_TAR_ZSTD
|
||||||
|
? [
|
||||||
|
'&&',
|
||||||
|
'zstd -T0 --long=30 -o',
|
||||||
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
constants_1.TarFilename
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
'--use-compress-program',
|
||||||
|
IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30'
|
||||||
|
];
|
||||||
|
case constants_1.CompressionMethod.ZstdWithoutLong:
|
||||||
|
return BSD_TAR_ZSTD
|
||||||
|
? [
|
||||||
|
'&&',
|
||||||
|
'zstd -T0 -o',
|
||||||
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
constants_1.TarFilename
|
||||||
|
]
|
||||||
|
: ['--use-compress-program', IS_WINDOWS ? '"zstd -T0"' : 'zstdmt'];
|
||||||
|
default:
|
||||||
|
return ['-z'];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function listTar(archivePath, compressionMethod) {
|
function listTar(archivePath, compressionMethod) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const args = [
|
const args = yield getArgs(compressionMethod, 'list', archivePath);
|
||||||
...getCompressionProgram(compressionMethod),
|
try {
|
||||||
'-tf',
|
yield exec_1.exec(args);
|
||||||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
}
|
||||||
'-P'
|
catch (error) {
|
||||||
];
|
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
||||||
yield execTar(args, compressionMethod);
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.listTar = listTar;
|
exports.listTar = listTar;
|
||||||
|
|
@ -38143,57 +38310,27 @@ function extractTar(archivePath, compressionMethod) {
|
||||||
// Create directory to extract tar into
|
// Create directory to extract tar into
|
||||||
const workingDirectory = getWorkingDirectory();
|
const workingDirectory = getWorkingDirectory();
|
||||||
yield io.mkdirP(workingDirectory);
|
yield io.mkdirP(workingDirectory);
|
||||||
const args = [
|
const args = yield getArgs(compressionMethod, 'extract', archivePath);
|
||||||
...getCompressionProgram(compressionMethod),
|
try {
|
||||||
'-xf',
|
yield exec_1.exec(args);
|
||||||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
}
|
||||||
'-P',
|
catch (error) {
|
||||||
'-C',
|
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
||||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
|
}
|
||||||
];
|
|
||||||
yield execTar(args, compressionMethod);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.extractTar = extractTar;
|
exports.extractTar = extractTar;
|
||||||
function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// Write source directories to manifest.txt to avoid command length limits
|
// Write source directories to manifest.txt to avoid command length limits
|
||||||
const manifestFilename = 'manifest.txt';
|
fs_1.writeFileSync(path.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join('\n'));
|
||||||
const cacheFileName = utils.getCacheFileName(compressionMethod);
|
const args = yield getArgs(compressionMethod, 'create');
|
||||||
fs_1.writeFileSync(path.join(archiveFolder, manifestFilename), sourceDirectories.join('\n'));
|
try {
|
||||||
const workingDirectory = getWorkingDirectory();
|
yield exec_1.exec(args, undefined, { cwd: archiveFolder });
|
||||||
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
|
}
|
||||||
// zstdmt is equivalent to 'zstd -T0'
|
catch (error) {
|
||||||
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
||||||
// Using 30 here because we also support 32-bit self-hosted runners.
|
|
||||||
// Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
|
|
||||||
function getCompressionProgram() {
|
|
||||||
switch (compressionMethod) {
|
|
||||||
case constants_1.CompressionMethod.Zstd:
|
|
||||||
return [
|
|
||||||
'--use-compress-program',
|
|
||||||
IS_WINDOWS ? 'zstd -T0 --long=30' : 'zstdmt --long=30'
|
|
||||||
];
|
|
||||||
case constants_1.CompressionMethod.ZstdWithoutLong:
|
|
||||||
return ['--use-compress-program', IS_WINDOWS ? 'zstd -T0' : 'zstdmt'];
|
|
||||||
default:
|
|
||||||
return ['-z'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const args = [
|
|
||||||
'--posix',
|
|
||||||
...getCompressionProgram(),
|
|
||||||
'-cf',
|
|
||||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
||||||
'--exclude',
|
|
||||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
||||||
'-P',
|
|
||||||
'-C',
|
|
||||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
||||||
'--files-from',
|
|
||||||
manifestFilename
|
|
||||||
];
|
|
||||||
yield execTar(args, compressionMethod, archiveFolder);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.createTar = createTar;
|
exports.createTar = createTar;
|
||||||
|
|
@ -38428,7 +38565,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.getCacheState = exports.setOutputAndState = exports.setCacheHitOutput = exports.setCacheState = exports.isExactKeyMatch = exports.isGhes = void 0;
|
exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.setCacheHitOutput = exports.isExactKeyMatch = exports.isGhes = void 0;
|
||||||
const cache = __importStar(__webpack_require__(692));
|
const cache = __importStar(__webpack_require__(692));
|
||||||
const core = __importStar(__webpack_require__(470));
|
const core = __importStar(__webpack_require__(470));
|
||||||
const constants_1 = __webpack_require__(196);
|
const constants_1 = __webpack_require__(196);
|
||||||
|
|
@ -38444,29 +38581,10 @@ function isExactKeyMatch(key, cacheKey) {
|
||||||
}) === 0);
|
}) === 0);
|
||||||
}
|
}
|
||||||
exports.isExactKeyMatch = isExactKeyMatch;
|
exports.isExactKeyMatch = isExactKeyMatch;
|
||||||
function setCacheState(state) {
|
|
||||||
core.saveState(constants_1.State.CacheMatchedKey, state);
|
|
||||||
}
|
|
||||||
exports.setCacheState = setCacheState;
|
|
||||||
function setCacheHitOutput(isCacheHit) {
|
function setCacheHitOutput(isCacheHit) {
|
||||||
core.setOutput(constants_1.Outputs.CacheHit, isCacheHit.toString());
|
core.setOutput(constants_1.Outputs.CacheHit, isCacheHit.toString());
|
||||||
}
|
}
|
||||||
exports.setCacheHitOutput = setCacheHitOutput;
|
exports.setCacheHitOutput = setCacheHitOutput;
|
||||||
function setOutputAndState(key, cacheKey) {
|
|
||||||
setCacheHitOutput(isExactKeyMatch(key, cacheKey));
|
|
||||||
// Store the matched cache key if it exists
|
|
||||||
cacheKey && setCacheState(cacheKey);
|
|
||||||
}
|
|
||||||
exports.setOutputAndState = setOutputAndState;
|
|
||||||
function getCacheState() {
|
|
||||||
const cacheKey = core.getState(constants_1.State.CacheMatchedKey);
|
|
||||||
if (cacheKey) {
|
|
||||||
core.debug(`Cache state/key: ${cacheKey}`);
|
|
||||||
return cacheKey;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
exports.getCacheState = getCacheState;
|
|
||||||
function logWarning(message) {
|
function logWarning(message) {
|
||||||
const warningPrefix = "[warning]";
|
const warningPrefix = "[warning]";
|
||||||
core.info(`${warningPrefix}${message}`);
|
core.info(`${warningPrefix}${message}`);
|
||||||
|
|
@ -38495,17 +38613,16 @@ function getInputAsInt(name, options) {
|
||||||
}
|
}
|
||||||
exports.getInputAsInt = getInputAsInt;
|
exports.getInputAsInt = getInputAsInt;
|
||||||
function isCacheFeatureAvailable() {
|
function isCacheFeatureAvailable() {
|
||||||
if (!cache.isFeatureAvailable()) {
|
if (cache.isFeatureAvailable()) {
|
||||||
if (isGhes()) {
|
return true;
|
||||||
logWarning(`Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.
|
}
|
||||||
|
if (isGhes()) {
|
||||||
|
logWarning(`Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.
|
||||||
Otherwise please upgrade to GHES version >= 3.5 and If you are also using Github Connect, please unretire the actions/cache namespace before upgrade (see https://docs.github.com/en/enterprise-server@3.5/admin/github-actions/managing-access-to-actions-from-githubcom/enabling-automatic-access-to-githubcom-actions-using-github-connect#automatic-retirement-of-namespaces-for-actions-accessed-on-githubcom)`);
|
Otherwise please upgrade to GHES version >= 3.5 and If you are also using Github Connect, please unretire the actions/cache namespace before upgrade (see https://docs.github.com/en/enterprise-server@3.5/admin/github-actions/managing-access-to-actions-from-githubcom/enabling-automatic-access-to-githubcom-actions-using-github-connect#automatic-retirement-of-namespaces-for-actions-accessed-on-githubcom)`);
|
||||||
}
|
|
||||||
else {
|
|
||||||
logWarning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions.");
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
logWarning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
|
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
|
||||||
|
|
||||||
|
|
@ -38619,7 +38736,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
|
||||||
|
|
||||||
var Stream = _interopDefault(__webpack_require__(794));
|
var Stream = _interopDefault(__webpack_require__(794));
|
||||||
var http = _interopDefault(__webpack_require__(605));
|
var http = _interopDefault(__webpack_require__(605));
|
||||||
var Url = _interopDefault(__webpack_require__(835));
|
var Url = _interopDefault(__webpack_require__(414));
|
||||||
var whatwgUrl = _interopDefault(__webpack_require__(70));
|
var whatwgUrl = _interopDefault(__webpack_require__(70));
|
||||||
var https = _interopDefault(__webpack_require__(211));
|
var https = _interopDefault(__webpack_require__(211));
|
||||||
var zlib = _interopDefault(__webpack_require__(761));
|
var zlib = _interopDefault(__webpack_require__(761));
|
||||||
|
|
@ -44133,318 +44250,7 @@ exports.default = _default;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 640 */
|
/* 640 */,
|
||||||
/***/ (function(module) {
|
|
||||||
|
|
||||||
/*! *****************************************************************************
|
|
||||||
Copyright (c) Microsoft Corporation.
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
***************************************************************************** */
|
|
||||||
/* global global, define, System, Reflect, Promise */
|
|
||||||
var __extends;
|
|
||||||
var __assign;
|
|
||||||
var __rest;
|
|
||||||
var __decorate;
|
|
||||||
var __param;
|
|
||||||
var __metadata;
|
|
||||||
var __awaiter;
|
|
||||||
var __generator;
|
|
||||||
var __exportStar;
|
|
||||||
var __values;
|
|
||||||
var __read;
|
|
||||||
var __spread;
|
|
||||||
var __spreadArrays;
|
|
||||||
var __spreadArray;
|
|
||||||
var __await;
|
|
||||||
var __asyncGenerator;
|
|
||||||
var __asyncDelegator;
|
|
||||||
var __asyncValues;
|
|
||||||
var __makeTemplateObject;
|
|
||||||
var __importStar;
|
|
||||||
var __importDefault;
|
|
||||||
var __classPrivateFieldGet;
|
|
||||||
var __classPrivateFieldSet;
|
|
||||||
var __createBinding;
|
|
||||||
(function (factory) {
|
|
||||||
var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
|
|
||||||
if (typeof define === "function" && define.amd) {
|
|
||||||
define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
|
|
||||||
}
|
|
||||||
else if ( true && typeof module.exports === "object") {
|
|
||||||
factory(createExporter(root, createExporter(module.exports)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
factory(createExporter(root));
|
|
||||||
}
|
|
||||||
function createExporter(exports, previous) {
|
|
||||||
if (exports !== root) {
|
|
||||||
if (typeof Object.create === "function") {
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
exports.__esModule = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
|
|
||||||
}
|
|
||||||
})
|
|
||||||
(function (exporter) {
|
|
||||||
var extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
|
|
||||||
__extends = function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
|
|
||||||
__assign = Object.assign || function (t) {
|
|
||||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
||||||
s = arguments[i];
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
|
|
||||||
__rest = function (s, e) {
|
|
||||||
var t = {};
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
||||||
t[p] = s[p];
|
|
||||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
||||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
||||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
||||||
t[p[i]] = s[p[i]];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
|
|
||||||
__decorate = function (decorators, target, key, desc) {
|
|
||||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
||||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
||||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
||||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
||||||
};
|
|
||||||
|
|
||||||
__param = function (paramIndex, decorator) {
|
|
||||||
return function (target, key) { decorator(target, key, paramIndex); }
|
|
||||||
};
|
|
||||||
|
|
||||||
__metadata = function (metadataKey, metadataValue) {
|
|
||||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
__awaiter = function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
__generator = function (thisArg, body) {
|
|
||||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
||||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
||||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
||||||
function step(op) {
|
|
||||||
if (f) throw new TypeError("Generator is already executing.");
|
|
||||||
while (_) try {
|
|
||||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
||||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
||||||
switch (op[0]) {
|
|
||||||
case 0: case 1: t = op; break;
|
|
||||||
case 4: _.label++; return { value: op[1], done: false };
|
|
||||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
||||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
||||||
default:
|
|
||||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
||||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
||||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
||||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
||||||
if (t[2]) _.ops.pop();
|
|
||||||
_.trys.pop(); continue;
|
|
||||||
}
|
|
||||||
op = body.call(thisArg, _);
|
|
||||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
||||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
__exportStar = function(m, o) {
|
|
||||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
|
|
||||||
};
|
|
||||||
|
|
||||||
__createBinding = Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
});
|
|
||||||
|
|
||||||
__values = function (o) {
|
|
||||||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
||||||
if (m) return m.call(o);
|
|
||||||
if (o && typeof o.length === "number") return {
|
|
||||||
next: function () {
|
|
||||||
if (o && i >= o.length) o = void 0;
|
|
||||||
return { value: o && o[i++], done: !o };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
||||||
};
|
|
||||||
|
|
||||||
__read = function (o, n) {
|
|
||||||
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
||||||
if (!m) return o;
|
|
||||||
var i = m.call(o), r, ar = [], e;
|
|
||||||
try {
|
|
||||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
||||||
}
|
|
||||||
catch (error) { e = { error: error }; }
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
||||||
}
|
|
||||||
finally { if (e) throw e.error; }
|
|
||||||
}
|
|
||||||
return ar;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
__spread = function () {
|
|
||||||
for (var ar = [], i = 0; i < arguments.length; i++)
|
|
||||||
ar = ar.concat(__read(arguments[i]));
|
|
||||||
return ar;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
__spreadArrays = function () {
|
|
||||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
||||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
||||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
||||||
r[k] = a[j];
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
|
|
||||||
__spreadArray = function (to, from, pack) {
|
|
||||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
||||||
if (ar || !(i in from)) {
|
|
||||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
||||||
ar[i] = from[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return to.concat(ar || Array.prototype.slice.call(from));
|
|
||||||
};
|
|
||||||
|
|
||||||
__await = function (v) {
|
|
||||||
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
||||||
};
|
|
||||||
|
|
||||||
__asyncGenerator = function (thisArg, _arguments, generator) {
|
|
||||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
||||||
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
||||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
||||||
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
||||||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
||||||
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
||||||
function fulfill(value) { resume("next", value); }
|
|
||||||
function reject(value) { resume("throw", value); }
|
|
||||||
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
||||||
};
|
|
||||||
|
|
||||||
__asyncDelegator = function (o) {
|
|
||||||
var i, p;
|
|
||||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
|
||||||
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
|
|
||||||
};
|
|
||||||
|
|
||||||
__asyncValues = function (o) {
|
|
||||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
||||||
var m = o[Symbol.asyncIterator], i;
|
|
||||||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
||||||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
||||||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
||||||
};
|
|
||||||
|
|
||||||
__makeTemplateObject = function (cooked, raw) {
|
|
||||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
||||||
return cooked;
|
|
||||||
};
|
|
||||||
|
|
||||||
var __setModuleDefault = Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
};
|
|
||||||
|
|
||||||
__importStar = function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
__importDefault = function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
|
|
||||||
__classPrivateFieldGet = function (receiver, state, kind, f) {
|
|
||||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
||||||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
||||||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
||||||
};
|
|
||||||
|
|
||||||
__classPrivateFieldSet = function (receiver, state, value, kind, f) {
|
|
||||||
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
||||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
||||||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
||||||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
||||||
};
|
|
||||||
|
|
||||||
exporter("__extends", __extends);
|
|
||||||
exporter("__assign", __assign);
|
|
||||||
exporter("__rest", __rest);
|
|
||||||
exporter("__decorate", __decorate);
|
|
||||||
exporter("__param", __param);
|
|
||||||
exporter("__metadata", __metadata);
|
|
||||||
exporter("__awaiter", __awaiter);
|
|
||||||
exporter("__generator", __generator);
|
|
||||||
exporter("__exportStar", __exportStar);
|
|
||||||
exporter("__createBinding", __createBinding);
|
|
||||||
exporter("__values", __values);
|
|
||||||
exporter("__read", __read);
|
|
||||||
exporter("__spread", __spread);
|
|
||||||
exporter("__spreadArrays", __spreadArrays);
|
|
||||||
exporter("__spreadArray", __spreadArray);
|
|
||||||
exporter("__await", __await);
|
|
||||||
exporter("__asyncGenerator", __asyncGenerator);
|
|
||||||
exporter("__asyncDelegator", __asyncDelegator);
|
|
||||||
exporter("__asyncValues", __asyncValues);
|
|
||||||
exporter("__makeTemplateObject", __makeTemplateObject);
|
|
||||||
exporter("__importStar", __importStar);
|
|
||||||
exporter("__importDefault", __importDefault);
|
|
||||||
exporter("__classPrivateFieldGet", __classPrivateFieldGet);
|
|
||||||
exporter("__classPrivateFieldSet", __classPrivateFieldSet);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
/* 641 */,
|
/* 641 */,
|
||||||
/* 642 */,
|
/* 642 */,
|
||||||
/* 643 */,
|
/* 643 */,
|
||||||
|
|
@ -47336,6 +47142,7 @@ const path = __importStar(__webpack_require__(622));
|
||||||
const utils = __importStar(__webpack_require__(15));
|
const utils = __importStar(__webpack_require__(15));
|
||||||
const cacheHttpClient = __importStar(__webpack_require__(114));
|
const cacheHttpClient = __importStar(__webpack_require__(114));
|
||||||
const tar_1 = __webpack_require__(434);
|
const tar_1 = __webpack_require__(434);
|
||||||
|
const constants_1 = __webpack_require__(931);
|
||||||
class ValidationError extends Error {
|
class ValidationError extends Error {
|
||||||
constructor(message) {
|
constructor(message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
@ -47397,13 +47204,33 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
checkKey(key);
|
checkKey(key);
|
||||||
}
|
}
|
||||||
const compressionMethod = yield utils.getCompressionMethod();
|
let cacheEntry;
|
||||||
|
let compressionMethod = yield utils.getCompressionMethod();
|
||||||
let archivePath = '';
|
let archivePath = '';
|
||||||
try {
|
try {
|
||||||
// path are needed to compute version
|
try {
|
||||||
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
// path are needed to compute version
|
||||||
compressionMethod
|
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||||
});
|
compressionMethod
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
// This is to support the old cache entry created
|
||||||
|
// by the old version of the cache action on windows.
|
||||||
|
if (process.platform === 'win32' &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip) {
|
||||||
|
compressionMethod = constants_1.CompressionMethod.Gzip;
|
||||||
|
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||||
|
compressionMethod
|
||||||
|
});
|
||||||
|
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||||
// Cache not found
|
// Cache not found
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -48958,29 +48785,6 @@ module.exports = function(dst, src) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
||||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
||||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
||||||
}
|
|
||||||
Object.defineProperty(o, k2, desc);
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
|
@ -48990,60 +48794,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const cache = __importStar(__webpack_require__(692));
|
const restoreImpl_1 = __importDefault(__webpack_require__(835));
|
||||||
const core = __importStar(__webpack_require__(470));
|
const stateProvider_1 = __webpack_require__(309);
|
||||||
const constants_1 = __webpack_require__(196);
|
|
||||||
const utils = __importStar(__webpack_require__(443));
|
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
yield (0, restoreImpl_1.default)(new stateProvider_1.StateProvider());
|
||||||
if (!utils.isCacheFeatureAvailable()) {
|
|
||||||
utils.setCacheHitOutput(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Validate inputs, this can cause task failure
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true });
|
|
||||||
core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
|
|
||||||
const restoreKeys = utils.getInputAsArray(constants_1.Inputs.RestoreKeys);
|
|
||||||
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
|
|
||||||
required: true
|
|
||||||
});
|
|
||||||
const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys);
|
|
||||||
//Check if user wants to save cache despite of failure in any previous job
|
|
||||||
const saveCache = core.getInput(constants_1.Inputs.SaveOnAnyFailure).toLowerCase();
|
|
||||||
if (saveCache == "true") {
|
|
||||||
core.debug(`Exporting environment variable ${constants_1.Variables.SaveCacheOnAnyFailure}`);
|
|
||||||
core.exportVariable(constants_1.Variables.SaveCacheOnAnyFailure, saveCache);
|
|
||||||
core.info(`Input Variable ${constants_1.Variables.SaveCacheOnAnyFailure} is set to true, the cache will be saved despite of any failure in the build.`);
|
|
||||||
}
|
|
||||||
if (!cacheKey) {
|
|
||||||
if (core.getInput(constants_1.Inputs.FailOnCacheMiss).toLowerCase() == "true") {
|
|
||||||
throw new Error(`Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the fail-on-cache-miss requirement is not met.`);
|
|
||||||
}
|
|
||||||
core.info(`Cache not found for input keys: ${[
|
|
||||||
primaryKey,
|
|
||||||
...restoreKeys
|
|
||||||
].join(", ")}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Store the matched cache key
|
|
||||||
utils.setCacheState(cacheKey);
|
|
||||||
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
|
|
||||||
utils.setCacheHitOutput(isExactKeyMatch);
|
|
||||||
if (!isExactKeyMatch &&
|
|
||||||
core.getBooleanInput(constants_1.Inputs.FailOnCacheMiss) == true) {
|
|
||||||
throw new Error(`Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the fail-on-cache-miss requirement is not met.`);
|
|
||||||
}
|
|
||||||
core.info(`Cache restored from key: ${cacheKey}`);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
core.setFailed(error.message);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
run();
|
run();
|
||||||
|
|
@ -49489,7 +49248,7 @@ var util = __webpack_require__(669);
|
||||||
var path = __webpack_require__(622);
|
var path = __webpack_require__(622);
|
||||||
var http = __webpack_require__(605);
|
var http = __webpack_require__(605);
|
||||||
var https = __webpack_require__(211);
|
var https = __webpack_require__(211);
|
||||||
var parseUrl = __webpack_require__(835).parse;
|
var parseUrl = __webpack_require__(414).parse;
|
||||||
var fs = __webpack_require__(747);
|
var fs = __webpack_require__(747);
|
||||||
var Stream = __webpack_require__(794).Stream;
|
var Stream = __webpack_require__(794).Stream;
|
||||||
var mime = __webpack_require__(779);
|
var mime = __webpack_require__(779);
|
||||||
|
|
@ -50655,9 +50414,87 @@ exports.VERSION = '1.0.4';
|
||||||
/* 833 */,
|
/* 833 */,
|
||||||
/* 834 */,
|
/* 834 */,
|
||||||
/* 835 */
|
/* 835 */
|
||||||
/***/ (function(module) {
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const cache = __importStar(__webpack_require__(692));
|
||||||
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
const constants_1 = __webpack_require__(196);
|
||||||
|
const utils = __importStar(__webpack_require__(443));
|
||||||
|
function restoreImpl(stateProvider) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
try {
|
||||||
|
if (!utils.isCacheFeatureAvailable()) {
|
||||||
|
utils.setCacheHitOutput(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Validate inputs, this can cause task failure
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true });
|
||||||
|
stateProvider.setState(constants_1.State.CachePrimaryKey, primaryKey);
|
||||||
|
const restoreKeys = utils.getInputAsArray(constants_1.Inputs.RestoreKeys);
|
||||||
|
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys);
|
||||||
|
if (!cacheKey) {
|
||||||
|
core.info(`Cache not found for input keys: ${[
|
||||||
|
primaryKey,
|
||||||
|
...restoreKeys
|
||||||
|
].join(", ")}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Store the matched cache key in states
|
||||||
|
stateProvider.setState(constants_1.State.CacheMatchedKey, cacheKey);
|
||||||
|
const isExactKeyMatch = utils.isExactKeyMatch(core.getInput(constants_1.Inputs.Key, { required: true }), cacheKey);
|
||||||
|
core.setOutput(constants_1.Outputs.CacheHit, isExactKeyMatch.toString());
|
||||||
|
core.info(`Cache restored from key: ${cacheKey}`);
|
||||||
|
return cacheKey;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
core.setFailed(error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.default = restoreImpl;
|
||||||
|
|
||||||
module.exports = require("url");
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 836 */,
|
/* 836 */,
|
||||||
|
|
@ -53506,6 +53343,11 @@ var CompressionMethod;
|
||||||
CompressionMethod["ZstdWithoutLong"] = "zstd-without-long";
|
CompressionMethod["ZstdWithoutLong"] = "zstd-without-long";
|
||||||
CompressionMethod["Zstd"] = "zstd";
|
CompressionMethod["Zstd"] = "zstd";
|
||||||
})(CompressionMethod = exports.CompressionMethod || (exports.CompressionMethod = {}));
|
})(CompressionMethod = exports.CompressionMethod || (exports.CompressionMethod = {}));
|
||||||
|
var ArchiveToolType;
|
||||||
|
(function (ArchiveToolType) {
|
||||||
|
ArchiveToolType["GNU"] = "gnu";
|
||||||
|
ArchiveToolType["BSD"] = "bsd";
|
||||||
|
})(ArchiveToolType = exports.ArchiveToolType || (exports.ArchiveToolType = {}));
|
||||||
// The default number of retry attempts.
|
// The default number of retry attempts.
|
||||||
exports.DefaultRetryAttempts = 2;
|
exports.DefaultRetryAttempts = 2;
|
||||||
// The default delay in milliseconds between retry attempts.
|
// The default delay in milliseconds between retry attempts.
|
||||||
|
|
@ -53514,6 +53356,12 @@ exports.DefaultRetryDelay = 5000;
|
||||||
// over the socket during this period, the socket is destroyed and the download
|
// over the socket during this period, the socket is destroyed and the download
|
||||||
// is aborted.
|
// is aborted.
|
||||||
exports.SocketTimeout = 5000;
|
exports.SocketTimeout = 5000;
|
||||||
|
// The default path of GNUtar on hosted Windows runners
|
||||||
|
exports.GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`;
|
||||||
|
// The default path of BSDtar on hosted Windows runners
|
||||||
|
exports.SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`;
|
||||||
|
exports.TarFilename = 'cache.tar';
|
||||||
|
exports.ManifestFilename = 'manifest.txt';
|
||||||
//# sourceMappingURL=constants.js.map
|
//# sourceMappingURL=constants.js.map
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
@ -55792,7 +55640,7 @@ var stream = __webpack_require__(794);
|
||||||
var FormData = __webpack_require__(790);
|
var FormData = __webpack_require__(790);
|
||||||
var node_fetch = __webpack_require__(454);
|
var node_fetch = __webpack_require__(454);
|
||||||
var coreTracing = __webpack_require__(263);
|
var coreTracing = __webpack_require__(263);
|
||||||
var url = __webpack_require__(835);
|
var url = __webpack_require__(414);
|
||||||
__webpack_require__(97);
|
__webpack_require__(97);
|
||||||
|
|
||||||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1177,10 +1177,6 @@ function getVersion(app) {
|
||||||
// Use zstandard if possible to maximize cache performance
|
// Use zstandard if possible to maximize cache performance
|
||||||
function getCompressionMethod() {
|
function getCompressionMethod() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (process.platform === 'win32' && !(yield isGnuTarInstalled())) {
|
|
||||||
// Disable zstd due to bug https://github.com/actions/cache/issues/301
|
|
||||||
return constants_1.CompressionMethod.Gzip;
|
|
||||||
}
|
|
||||||
const versionOutput = yield getVersion('zstd');
|
const versionOutput = yield getVersion('zstd');
|
||||||
const version = semver.clean(versionOutput);
|
const version = semver.clean(versionOutput);
|
||||||
if (!versionOutput.toLowerCase().includes('zstd command line interface')) {
|
if (!versionOutput.toLowerCase().includes('zstd command line interface')) {
|
||||||
|
|
@ -1204,13 +1200,16 @@ function getCacheFileName(compressionMethod) {
|
||||||
: constants_1.CacheFilename.Zstd;
|
: constants_1.CacheFilename.Zstd;
|
||||||
}
|
}
|
||||||
exports.getCacheFileName = getCacheFileName;
|
exports.getCacheFileName = getCacheFileName;
|
||||||
function isGnuTarInstalled() {
|
function getGnuTarPathOnWindows() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (fs.existsSync(constants_1.GnuTarPathOnWindows)) {
|
||||||
|
return constants_1.GnuTarPathOnWindows;
|
||||||
|
}
|
||||||
const versionOutput = yield getVersion('tar');
|
const versionOutput = yield getVersion('tar');
|
||||||
return versionOutput.toLowerCase().includes('gnu tar');
|
return versionOutput.toLowerCase().includes('gnu tar') ? io.which('tar') : '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.isGnuTarInstalled = isGnuTarInstalled;
|
exports.getGnuTarPathOnWindows = getGnuTarPathOnWindows;
|
||||||
function assertDefined(name, value) {
|
function assertDefined(name, value) {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
throw Error(`Expected ${name} but value was undefiend`);
|
throw Error(`Expected ${name} but value was undefiend`);
|
||||||
|
|
@ -3046,19 +3045,18 @@ exports.default = _default;
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 105 */,
|
/* 105 */,
|
||||||
/* 106 */
|
/* 106 */
|
||||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
/***/ (function(__unusedmodule, exports) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', { value: true });
|
Object.defineProperty(exports, '__esModule', { value: true });
|
||||||
|
|
||||||
var tslib = __webpack_require__(640);
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
var listenersMap = new WeakMap();
|
/// <reference path="../shims-public.d.ts" />
|
||||||
var abortedMap = new WeakMap();
|
const listenersMap = new WeakMap();
|
||||||
|
const abortedMap = new WeakMap();
|
||||||
/**
|
/**
|
||||||
* An aborter instance implements AbortSignal interface, can abort HTTP requests.
|
* An aborter instance implements AbortSignal interface, can abort HTTP requests.
|
||||||
*
|
*
|
||||||
|
|
@ -3072,8 +3070,8 @@ var abortedMap = new WeakMap();
|
||||||
* await doAsyncWork(AbortSignal.none);
|
* await doAsyncWork(AbortSignal.none);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
var AbortSignal = /** @class */ (function () {
|
class AbortSignal {
|
||||||
function AbortSignal() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
* onabort event listener.
|
* onabort event listener.
|
||||||
*/
|
*/
|
||||||
|
|
@ -3081,74 +3079,65 @@ var AbortSignal = /** @class */ (function () {
|
||||||
listenersMap.set(this, []);
|
listenersMap.set(this, []);
|
||||||
abortedMap.set(this, false);
|
abortedMap.set(this, false);
|
||||||
}
|
}
|
||||||
Object.defineProperty(AbortSignal.prototype, "aborted", {
|
/**
|
||||||
/**
|
* Status of whether aborted or not.
|
||||||
* Status of whether aborted or not.
|
*
|
||||||
*
|
* @readonly
|
||||||
* @readonly
|
*/
|
||||||
*/
|
get aborted() {
|
||||||
get: function () {
|
if (!abortedMap.has(this)) {
|
||||||
if (!abortedMap.has(this)) {
|
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
||||||
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
}
|
||||||
}
|
return abortedMap.get(this);
|
||||||
return abortedMap.get(this);
|
}
|
||||||
},
|
/**
|
||||||
enumerable: false,
|
* Creates a new AbortSignal instance that will never be aborted.
|
||||||
configurable: true
|
*
|
||||||
});
|
* @readonly
|
||||||
Object.defineProperty(AbortSignal, "none", {
|
*/
|
||||||
/**
|
static get none() {
|
||||||
* Creates a new AbortSignal instance that will never be aborted.
|
return new AbortSignal();
|
||||||
*
|
}
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
get: function () {
|
|
||||||
return new AbortSignal();
|
|
||||||
},
|
|
||||||
enumerable: false,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* Added new "abort" event listener, only support "abort" event.
|
* Added new "abort" event listener, only support "abort" event.
|
||||||
*
|
*
|
||||||
* @param _type - Only support "abort" event
|
* @param _type - Only support "abort" event
|
||||||
* @param listener - The listener to be added
|
* @param listener - The listener to be added
|
||||||
*/
|
*/
|
||||||
AbortSignal.prototype.addEventListener = function (
|
addEventListener(
|
||||||
// tslint:disable-next-line:variable-name
|
// tslint:disable-next-line:variable-name
|
||||||
_type, listener) {
|
_type, listener) {
|
||||||
if (!listenersMap.has(this)) {
|
if (!listenersMap.has(this)) {
|
||||||
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
||||||
}
|
}
|
||||||
var listeners = listenersMap.get(this);
|
const listeners = listenersMap.get(this);
|
||||||
listeners.push(listener);
|
listeners.push(listener);
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* Remove "abort" event listener, only support "abort" event.
|
* Remove "abort" event listener, only support "abort" event.
|
||||||
*
|
*
|
||||||
* @param _type - Only support "abort" event
|
* @param _type - Only support "abort" event
|
||||||
* @param listener - The listener to be removed
|
* @param listener - The listener to be removed
|
||||||
*/
|
*/
|
||||||
AbortSignal.prototype.removeEventListener = function (
|
removeEventListener(
|
||||||
// tslint:disable-next-line:variable-name
|
// tslint:disable-next-line:variable-name
|
||||||
_type, listener) {
|
_type, listener) {
|
||||||
if (!listenersMap.has(this)) {
|
if (!listenersMap.has(this)) {
|
||||||
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
throw new TypeError("Expected `this` to be an instance of AbortSignal.");
|
||||||
}
|
}
|
||||||
var listeners = listenersMap.get(this);
|
const listeners = listenersMap.get(this);
|
||||||
var index = listeners.indexOf(listener);
|
const index = listeners.indexOf(listener);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
listeners.splice(index, 1);
|
listeners.splice(index, 1);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* Dispatches a synthetic event to the AbortSignal.
|
* Dispatches a synthetic event to the AbortSignal.
|
||||||
*/
|
*/
|
||||||
AbortSignal.prototype.dispatchEvent = function (_event) {
|
dispatchEvent(_event) {
|
||||||
throw new Error("This is a stub dispatchEvent implementation that should not be used. It only exists for type-checking purposes.");
|
throw new Error("This is a stub dispatchEvent implementation that should not be used. It only exists for type-checking purposes.");
|
||||||
};
|
}
|
||||||
return AbortSignal;
|
}
|
||||||
}());
|
|
||||||
/**
|
/**
|
||||||
* Helper to trigger an abort event immediately, the onabort and all abort event listeners will be triggered.
|
* Helper to trigger an abort event immediately, the onabort and all abort event listeners will be triggered.
|
||||||
* Will try to trigger abort event for all linked AbortSignal nodes.
|
* Will try to trigger abort event for all linked AbortSignal nodes.
|
||||||
|
|
@ -3166,12 +3155,12 @@ function abortSignal(signal) {
|
||||||
if (signal.onabort) {
|
if (signal.onabort) {
|
||||||
signal.onabort.call(signal);
|
signal.onabort.call(signal);
|
||||||
}
|
}
|
||||||
var listeners = listenersMap.get(signal);
|
const listeners = listenersMap.get(signal);
|
||||||
if (listeners) {
|
if (listeners) {
|
||||||
// Create a copy of listeners so mutations to the array
|
// Create a copy of listeners so mutations to the array
|
||||||
// (e.g. via removeListener calls) don't affect the listeners
|
// (e.g. via removeListener calls) don't affect the listeners
|
||||||
// we invoke.
|
// we invoke.
|
||||||
listeners.slice().forEach(function (listener) {
|
listeners.slice().forEach((listener) => {
|
||||||
listener.call(signal, { type: "abort" });
|
listener.call(signal, { type: "abort" });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -3197,15 +3186,12 @@ function abortSignal(signal) {
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
var AbortError = /** @class */ (function (_super) {
|
class AbortError extends Error {
|
||||||
tslib.__extends(AbortError, _super);
|
constructor(message) {
|
||||||
function AbortError(message) {
|
super(message);
|
||||||
var _this = _super.call(this, message) || this;
|
this.name = "AbortError";
|
||||||
_this.name = "AbortError";
|
|
||||||
return _this;
|
|
||||||
}
|
}
|
||||||
return AbortError;
|
}
|
||||||
}(Error));
|
|
||||||
/**
|
/**
|
||||||
* An AbortController provides an AbortSignal and the associated controls to signal
|
* An AbortController provides an AbortSignal and the associated controls to signal
|
||||||
* that an asynchronous operation should be aborted.
|
* that an asynchronous operation should be aborted.
|
||||||
|
|
@ -3240,10 +3226,9 @@ var AbortError = /** @class */ (function (_super) {
|
||||||
* await doAsyncWork(aborter.withTimeout(25 * 1000));
|
* await doAsyncWork(aborter.withTimeout(25 * 1000));
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
var AbortController = /** @class */ (function () {
|
class AbortController {
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
function AbortController(parentSignals) {
|
constructor(parentSignals) {
|
||||||
var _this = this;
|
|
||||||
this._signal = new AbortSignal();
|
this._signal = new AbortSignal();
|
||||||
if (!parentSignals) {
|
if (!parentSignals) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -3253,8 +3238,7 @@ var AbortController = /** @class */ (function () {
|
||||||
// eslint-disable-next-line prefer-rest-params
|
// eslint-disable-next-line prefer-rest-params
|
||||||
parentSignals = arguments;
|
parentSignals = arguments;
|
||||||
}
|
}
|
||||||
for (var _i = 0, parentSignals_1 = parentSignals; _i < parentSignals_1.length; _i++) {
|
for (const parentSignal of parentSignals) {
|
||||||
var parentSignal = parentSignals_1[_i];
|
|
||||||
// if the parent signal has already had abort() called,
|
// if the parent signal has already had abort() called,
|
||||||
// then call abort on this signal as well.
|
// then call abort on this signal as well.
|
||||||
if (parentSignal.aborted) {
|
if (parentSignal.aborted) {
|
||||||
|
|
@ -3262,47 +3246,42 @@ var AbortController = /** @class */ (function () {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// when the parent signal aborts, this signal should as well.
|
// when the parent signal aborts, this signal should as well.
|
||||||
parentSignal.addEventListener("abort", function () {
|
parentSignal.addEventListener("abort", () => {
|
||||||
_this.abort();
|
this.abort();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object.defineProperty(AbortController.prototype, "signal", {
|
/**
|
||||||
/**
|
* The AbortSignal associated with this controller that will signal aborted
|
||||||
* The AbortSignal associated with this controller that will signal aborted
|
* when the abort method is called on this controller.
|
||||||
* when the abort method is called on this controller.
|
*
|
||||||
*
|
* @readonly
|
||||||
* @readonly
|
*/
|
||||||
*/
|
get signal() {
|
||||||
get: function () {
|
return this._signal;
|
||||||
return this._signal;
|
}
|
||||||
},
|
|
||||||
enumerable: false,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* Signal that any operations passed this controller's associated abort signal
|
* Signal that any operations passed this controller's associated abort signal
|
||||||
* to cancel any remaining work and throw an `AbortError`.
|
* to cancel any remaining work and throw an `AbortError`.
|
||||||
*/
|
*/
|
||||||
AbortController.prototype.abort = function () {
|
abort() {
|
||||||
abortSignal(this._signal);
|
abortSignal(this._signal);
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* Creates a new AbortSignal instance that will abort after the provided ms.
|
* Creates a new AbortSignal instance that will abort after the provided ms.
|
||||||
* @param ms - Elapsed time in milliseconds to trigger an abort.
|
* @param ms - Elapsed time in milliseconds to trigger an abort.
|
||||||
*/
|
*/
|
||||||
AbortController.timeout = function (ms) {
|
static timeout(ms) {
|
||||||
var signal = new AbortSignal();
|
const signal = new AbortSignal();
|
||||||
var timer = setTimeout(abortSignal, ms, signal);
|
const timer = setTimeout(abortSignal, ms, signal);
|
||||||
// Prevent the active Timer from keeping the Node.js event loop active.
|
// Prevent the active Timer from keeping the Node.js event loop active.
|
||||||
if (typeof timer.unref === "function") {
|
if (typeof timer.unref === "function") {
|
||||||
timer.unref();
|
timer.unref();
|
||||||
}
|
}
|
||||||
return signal;
|
return signal;
|
||||||
};
|
}
|
||||||
return AbortController;
|
}
|
||||||
}());
|
|
||||||
|
|
||||||
exports.AbortController = AbortController;
|
exports.AbortController = AbortController;
|
||||||
exports.AbortError = AbortError;
|
exports.AbortError = AbortError;
|
||||||
|
|
@ -4964,19 +4943,19 @@ exports.checkBypass = checkBypass;
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.RefKey = exports.Variables = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0;
|
exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0;
|
||||||
var Inputs;
|
var Inputs;
|
||||||
(function (Inputs) {
|
(function (Inputs) {
|
||||||
Inputs["Key"] = "key";
|
Inputs["Key"] = "key";
|
||||||
Inputs["Path"] = "path";
|
Inputs["Path"] = "path";
|
||||||
Inputs["RestoreKeys"] = "restore-keys";
|
Inputs["RestoreKeys"] = "restore-keys";
|
||||||
Inputs["UploadChunkSize"] = "upload-chunk-size";
|
Inputs["UploadChunkSize"] = "upload-chunk-size"; // Input for cache, save action
|
||||||
Inputs["FailOnCacheMiss"] = "fail-on-cache-miss";
|
|
||||||
Inputs["SaveOnAnyFailure"] = "save-on-any-failure";
|
|
||||||
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
||||||
var Outputs;
|
var Outputs;
|
||||||
(function (Outputs) {
|
(function (Outputs) {
|
||||||
Outputs["CacheHit"] = "cache-hit";
|
Outputs["CacheHit"] = "cache-hit";
|
||||||
|
Outputs["CachePrimaryKey"] = "cache-primary-key";
|
||||||
|
Outputs["CacheRestoreKey"] = "cache-restore-key"; // Output from restore action
|
||||||
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
||||||
var State;
|
var State;
|
||||||
(function (State) {
|
(function (State) {
|
||||||
|
|
@ -4989,10 +4968,6 @@ var Events;
|
||||||
Events["Push"] = "push";
|
Events["Push"] = "push";
|
||||||
Events["PullRequest"] = "pull_request";
|
Events["PullRequest"] = "pull_request";
|
||||||
})(Events = exports.Events || (exports.Events = {}));
|
})(Events = exports.Events || (exports.Events = {}));
|
||||||
var Variables;
|
|
||||||
(function (Variables) {
|
|
||||||
Variables["SaveCacheOnAnyFailure"] = "SAVE_CACHE_ON_ANY_FAILURE";
|
|
||||||
})(Variables = exports.Variables || (exports.Variables = {}));
|
|
||||||
exports.RefKey = "GITHUB_REF";
|
exports.RefKey = "GITHUB_REF";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -9350,7 +9325,80 @@ function expand(str, isTop) {
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 307 */,
|
/* 307 */,
|
||||||
/* 308 */,
|
/* 308 */,
|
||||||
/* 309 */,
|
/* 309 */
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.NullStateProvider = exports.StateProvider = void 0;
|
||||||
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
const constants_1 = __webpack_require__(196);
|
||||||
|
class StateProviderBase {
|
||||||
|
constructor() {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
||||||
|
this.setState = (key, value) => { };
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
this.getState = (key) => "";
|
||||||
|
}
|
||||||
|
getCacheState() {
|
||||||
|
const cacheKey = this.getState(constants_1.State.CacheMatchedKey);
|
||||||
|
if (cacheKey) {
|
||||||
|
core.debug(`Cache state/key: ${cacheKey}`);
|
||||||
|
return cacheKey;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class StateProvider extends StateProviderBase {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
this.setState = core.saveState;
|
||||||
|
this.getState = core.getState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.StateProvider = StateProvider;
|
||||||
|
class NullStateProvider extends StateProviderBase {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
this.stateToOutputMap = new Map([
|
||||||
|
[constants_1.State.CacheMatchedKey, constants_1.Outputs.CacheRestoreKey],
|
||||||
|
[constants_1.State.CachePrimaryKey, constants_1.Outputs.CachePrimaryKey]
|
||||||
|
]);
|
||||||
|
this.setState = (key, value) => {
|
||||||
|
core.setOutput(this.stateToOutputMap.get(key), value);
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
this.getState = (key) => "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.NullStateProvider = NullStateProvider;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
/* 310 */,
|
/* 310 */,
|
||||||
/* 311 */,
|
/* 311 */,
|
||||||
/* 312 */
|
/* 312 */
|
||||||
|
|
@ -38061,21 +38109,19 @@ const path = __importStar(__webpack_require__(622));
|
||||||
const utils = __importStar(__webpack_require__(15));
|
const utils = __importStar(__webpack_require__(15));
|
||||||
const constants_1 = __webpack_require__(931);
|
const constants_1 = __webpack_require__(931);
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
function getTarPath(args, compressionMethod) {
|
// Function also mutates the args array. For non-mutation call with passing an empty array.
|
||||||
|
function getTarPath() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case 'win32': {
|
case 'win32': {
|
||||||
const systemTar = `${process.env['windir']}\\System32\\tar.exe`;
|
const gnuTar = yield utils.getGnuTarPathOnWindows();
|
||||||
if (compressionMethod !== constants_1.CompressionMethod.Gzip) {
|
const systemTar = constants_1.SystemTarPathOnWindows;
|
||||||
// We only use zstandard compression on windows when gnu tar is installed due to
|
if (gnuTar) {
|
||||||
// a bug with compressing large files with bsdtar + zstd
|
// Use GNUtar as default on windows
|
||||||
args.push('--force-local');
|
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
|
||||||
}
|
}
|
||||||
else if (fs_1.existsSync(systemTar)) {
|
else if (fs_1.existsSync(systemTar)) {
|
||||||
return systemTar;
|
return { path: systemTar, type: constants_1.ArchiveToolType.BSD };
|
||||||
}
|
|
||||||
else if (yield utils.isGnuTarInstalled()) {
|
|
||||||
args.push('--force-local');
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -38083,24 +38129,83 @@ function getTarPath(args, compressionMethod) {
|
||||||
const gnuTar = yield io.which('gtar', false);
|
const gnuTar = yield io.which('gtar', false);
|
||||||
if (gnuTar) {
|
if (gnuTar) {
|
||||||
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
|
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
|
||||||
args.push('--delay-directory-restore');
|
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
|
||||||
return gnuTar;
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
path: yield io.which('tar', true),
|
||||||
|
type: constants_1.ArchiveToolType.BSD
|
||||||
|
};
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return yield io.which('tar', true);
|
return {
|
||||||
|
path: yield io.which('tar', true),
|
||||||
|
type: constants_1.ArchiveToolType.GNU
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function execTar(args, compressionMethod, cwd) {
|
// Return arguments for tar as per tarPath, compressionMethod, method type and os
|
||||||
|
function getTarArgs(tarPath, compressionMethod, type, archivePath = '') {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
const args = [`"${tarPath.path}"`];
|
||||||
yield exec_1.exec(`"${yield getTarPath(args, compressionMethod)}"`, args, { cwd });
|
const cacheFileName = utils.getCacheFileName(compressionMethod);
|
||||||
|
const tarFile = 'cache.tar';
|
||||||
|
const workingDirectory = getWorkingDirectory();
|
||||||
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
|
IS_WINDOWS;
|
||||||
|
// Method specific args
|
||||||
|
switch (type) {
|
||||||
|
case 'create':
|
||||||
|
args.push('--posix', '-cf', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--exclude', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--files-from', constants_1.ManifestFilename);
|
||||||
|
break;
|
||||||
|
case 'extract':
|
||||||
|
args.push('-xf', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'));
|
||||||
|
break;
|
||||||
|
case 'list':
|
||||||
|
args.push('-tf', BSD_TAR_ZSTD
|
||||||
|
? tarFile
|
||||||
|
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
catch (error) {
|
// Platform specific args
|
||||||
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
if (tarPath.type === constants_1.ArchiveToolType.GNU) {
|
||||||
|
switch (process.platform) {
|
||||||
|
case 'win32':
|
||||||
|
args.push('--force-local');
|
||||||
|
break;
|
||||||
|
case 'darwin':
|
||||||
|
args.push('--delay-directory-restore');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getArgs(compressionMethod, type, archivePath = '') {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const tarPath = yield getTarPath();
|
||||||
|
const tarArgs = yield getTarArgs(tarPath, compressionMethod, type, archivePath);
|
||||||
|
const compressionArgs = type !== 'create'
|
||||||
|
? yield getDecompressionProgram(tarPath, compressionMethod, archivePath)
|
||||||
|
: yield getCompressionProgram(tarPath, compressionMethod);
|
||||||
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
|
IS_WINDOWS;
|
||||||
|
if (BSD_TAR_ZSTD && type !== 'create') {
|
||||||
|
return [...compressionArgs, ...tarArgs].join(' ');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return [...tarArgs, ...compressionArgs].join(' ');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -38109,32 +38214,89 @@ function getWorkingDirectory() {
|
||||||
return (_a = process.env['GITHUB_WORKSPACE']) !== null && _a !== void 0 ? _a : process.cwd();
|
return (_a = process.env['GITHUB_WORKSPACE']) !== null && _a !== void 0 ? _a : process.cwd();
|
||||||
}
|
}
|
||||||
// Common function for extractTar and listTar to get the compression method
|
// Common function for extractTar and listTar to get the compression method
|
||||||
function getCompressionProgram(compressionMethod) {
|
function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
|
||||||
// -d: Decompress.
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// unzstd is equivalent to 'zstd -d'
|
// -d: Decompress.
|
||||||
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
// unzstd is equivalent to 'zstd -d'
|
||||||
// Using 30 here because we also support 32-bit self-hosted runners.
|
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
||||||
switch (compressionMethod) {
|
// Using 30 here because we also support 32-bit self-hosted runners.
|
||||||
case constants_1.CompressionMethod.Zstd:
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
return [
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
'--use-compress-program',
|
IS_WINDOWS;
|
||||||
IS_WINDOWS ? 'zstd -d --long=30' : 'unzstd --long=30'
|
switch (compressionMethod) {
|
||||||
];
|
case constants_1.CompressionMethod.Zstd:
|
||||||
case constants_1.CompressionMethod.ZstdWithoutLong:
|
return BSD_TAR_ZSTD
|
||||||
return ['--use-compress-program', IS_WINDOWS ? 'zstd -d' : 'unzstd'];
|
? [
|
||||||
default:
|
'zstd -d --long=30 -o',
|
||||||
return ['-z'];
|
constants_1.TarFilename,
|
||||||
}
|
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
'&&'
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
'--use-compress-program',
|
||||||
|
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
|
||||||
|
];
|
||||||
|
case constants_1.CompressionMethod.ZstdWithoutLong:
|
||||||
|
return BSD_TAR_ZSTD
|
||||||
|
? [
|
||||||
|
'zstd -d -o',
|
||||||
|
constants_1.TarFilename,
|
||||||
|
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
'&&'
|
||||||
|
]
|
||||||
|
: ['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd'];
|
||||||
|
default:
|
||||||
|
return ['-z'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
|
||||||
|
// zstdmt is equivalent to 'zstd -T0'
|
||||||
|
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
||||||
|
// Using 30 here because we also support 32-bit self-hosted runners.
|
||||||
|
// Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
|
||||||
|
function getCompressionProgram(tarPath, compressionMethod) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const cacheFileName = utils.getCacheFileName(compressionMethod);
|
||||||
|
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip &&
|
||||||
|
IS_WINDOWS;
|
||||||
|
switch (compressionMethod) {
|
||||||
|
case constants_1.CompressionMethod.Zstd:
|
||||||
|
return BSD_TAR_ZSTD
|
||||||
|
? [
|
||||||
|
'&&',
|
||||||
|
'zstd -T0 --long=30 -o',
|
||||||
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
constants_1.TarFilename
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
'--use-compress-program',
|
||||||
|
IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30'
|
||||||
|
];
|
||||||
|
case constants_1.CompressionMethod.ZstdWithoutLong:
|
||||||
|
return BSD_TAR_ZSTD
|
||||||
|
? [
|
||||||
|
'&&',
|
||||||
|
'zstd -T0 -o',
|
||||||
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
constants_1.TarFilename
|
||||||
|
]
|
||||||
|
: ['--use-compress-program', IS_WINDOWS ? '"zstd -T0"' : 'zstdmt'];
|
||||||
|
default:
|
||||||
|
return ['-z'];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function listTar(archivePath, compressionMethod) {
|
function listTar(archivePath, compressionMethod) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const args = [
|
const args = yield getArgs(compressionMethod, 'list', archivePath);
|
||||||
...getCompressionProgram(compressionMethod),
|
try {
|
||||||
'-tf',
|
yield exec_1.exec(args);
|
||||||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
}
|
||||||
'-P'
|
catch (error) {
|
||||||
];
|
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
||||||
yield execTar(args, compressionMethod);
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.listTar = listTar;
|
exports.listTar = listTar;
|
||||||
|
|
@ -38143,57 +38305,27 @@ function extractTar(archivePath, compressionMethod) {
|
||||||
// Create directory to extract tar into
|
// Create directory to extract tar into
|
||||||
const workingDirectory = getWorkingDirectory();
|
const workingDirectory = getWorkingDirectory();
|
||||||
yield io.mkdirP(workingDirectory);
|
yield io.mkdirP(workingDirectory);
|
||||||
const args = [
|
const args = yield getArgs(compressionMethod, 'extract', archivePath);
|
||||||
...getCompressionProgram(compressionMethod),
|
try {
|
||||||
'-xf',
|
yield exec_1.exec(args);
|
||||||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
}
|
||||||
'-P',
|
catch (error) {
|
||||||
'-C',
|
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
||||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
|
}
|
||||||
];
|
|
||||||
yield execTar(args, compressionMethod);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.extractTar = extractTar;
|
exports.extractTar = extractTar;
|
||||||
function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// Write source directories to manifest.txt to avoid command length limits
|
// Write source directories to manifest.txt to avoid command length limits
|
||||||
const manifestFilename = 'manifest.txt';
|
fs_1.writeFileSync(path.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join('\n'));
|
||||||
const cacheFileName = utils.getCacheFileName(compressionMethod);
|
const args = yield getArgs(compressionMethod, 'create');
|
||||||
fs_1.writeFileSync(path.join(archiveFolder, manifestFilename), sourceDirectories.join('\n'));
|
try {
|
||||||
const workingDirectory = getWorkingDirectory();
|
yield exec_1.exec(args, undefined, { cwd: archiveFolder });
|
||||||
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
|
}
|
||||||
// zstdmt is equivalent to 'zstd -T0'
|
catch (error) {
|
||||||
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
|
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
|
||||||
// Using 30 here because we also support 32-bit self-hosted runners.
|
|
||||||
// Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
|
|
||||||
function getCompressionProgram() {
|
|
||||||
switch (compressionMethod) {
|
|
||||||
case constants_1.CompressionMethod.Zstd:
|
|
||||||
return [
|
|
||||||
'--use-compress-program',
|
|
||||||
IS_WINDOWS ? 'zstd -T0 --long=30' : 'zstdmt --long=30'
|
|
||||||
];
|
|
||||||
case constants_1.CompressionMethod.ZstdWithoutLong:
|
|
||||||
return ['--use-compress-program', IS_WINDOWS ? 'zstd -T0' : 'zstdmt'];
|
|
||||||
default:
|
|
||||||
return ['-z'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const args = [
|
|
||||||
'--posix',
|
|
||||||
...getCompressionProgram(),
|
|
||||||
'-cf',
|
|
||||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
||||||
'--exclude',
|
|
||||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
||||||
'-P',
|
|
||||||
'-C',
|
|
||||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
|
||||||
'--files-from',
|
|
||||||
manifestFilename
|
|
||||||
];
|
|
||||||
yield execTar(args, compressionMethod, archiveFolder);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.createTar = createTar;
|
exports.createTar = createTar;
|
||||||
|
|
@ -38428,7 +38560,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.getCacheState = exports.setOutputAndState = exports.setCacheHitOutput = exports.setCacheState = exports.isExactKeyMatch = exports.isGhes = void 0;
|
exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.setCacheHitOutput = exports.isExactKeyMatch = exports.isGhes = void 0;
|
||||||
const cache = __importStar(__webpack_require__(692));
|
const cache = __importStar(__webpack_require__(692));
|
||||||
const core = __importStar(__webpack_require__(470));
|
const core = __importStar(__webpack_require__(470));
|
||||||
const constants_1 = __webpack_require__(196);
|
const constants_1 = __webpack_require__(196);
|
||||||
|
|
@ -38444,29 +38576,10 @@ function isExactKeyMatch(key, cacheKey) {
|
||||||
}) === 0);
|
}) === 0);
|
||||||
}
|
}
|
||||||
exports.isExactKeyMatch = isExactKeyMatch;
|
exports.isExactKeyMatch = isExactKeyMatch;
|
||||||
function setCacheState(state) {
|
|
||||||
core.saveState(constants_1.State.CacheMatchedKey, state);
|
|
||||||
}
|
|
||||||
exports.setCacheState = setCacheState;
|
|
||||||
function setCacheHitOutput(isCacheHit) {
|
function setCacheHitOutput(isCacheHit) {
|
||||||
core.setOutput(constants_1.Outputs.CacheHit, isCacheHit.toString());
|
core.setOutput(constants_1.Outputs.CacheHit, isCacheHit.toString());
|
||||||
}
|
}
|
||||||
exports.setCacheHitOutput = setCacheHitOutput;
|
exports.setCacheHitOutput = setCacheHitOutput;
|
||||||
function setOutputAndState(key, cacheKey) {
|
|
||||||
setCacheHitOutput(isExactKeyMatch(key, cacheKey));
|
|
||||||
// Store the matched cache key if it exists
|
|
||||||
cacheKey && setCacheState(cacheKey);
|
|
||||||
}
|
|
||||||
exports.setOutputAndState = setOutputAndState;
|
|
||||||
function getCacheState() {
|
|
||||||
const cacheKey = core.getState(constants_1.State.CacheMatchedKey);
|
|
||||||
if (cacheKey) {
|
|
||||||
core.debug(`Cache state/key: ${cacheKey}`);
|
|
||||||
return cacheKey;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
exports.getCacheState = getCacheState;
|
|
||||||
function logWarning(message) {
|
function logWarning(message) {
|
||||||
const warningPrefix = "[warning]";
|
const warningPrefix = "[warning]";
|
||||||
core.info(`${warningPrefix}${message}`);
|
core.info(`${warningPrefix}${message}`);
|
||||||
|
|
@ -38495,17 +38608,16 @@ function getInputAsInt(name, options) {
|
||||||
}
|
}
|
||||||
exports.getInputAsInt = getInputAsInt;
|
exports.getInputAsInt = getInputAsInt;
|
||||||
function isCacheFeatureAvailable() {
|
function isCacheFeatureAvailable() {
|
||||||
if (!cache.isFeatureAvailable()) {
|
if (cache.isFeatureAvailable()) {
|
||||||
if (isGhes()) {
|
return true;
|
||||||
logWarning(`Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.
|
}
|
||||||
|
if (isGhes()) {
|
||||||
|
logWarning(`Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.
|
||||||
Otherwise please upgrade to GHES version >= 3.5 and If you are also using Github Connect, please unretire the actions/cache namespace before upgrade (see https://docs.github.com/en/enterprise-server@3.5/admin/github-actions/managing-access-to-actions-from-githubcom/enabling-automatic-access-to-githubcom-actions-using-github-connect#automatic-retirement-of-namespaces-for-actions-accessed-on-githubcom)`);
|
Otherwise please upgrade to GHES version >= 3.5 and If you are also using Github Connect, please unretire the actions/cache namespace before upgrade (see https://docs.github.com/en/enterprise-server@3.5/admin/github-actions/managing-access-to-actions-from-githubcom/enabling-automatic-access-to-githubcom-actions-using-github-connect#automatic-retirement-of-namespaces-for-actions-accessed-on-githubcom)`);
|
||||||
}
|
|
||||||
else {
|
|
||||||
logWarning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions.");
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
logWarning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
|
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
|
||||||
|
|
||||||
|
|
@ -40899,7 +41011,96 @@ Object.defineProperty(exports, "toPlatformPath", { enumerable: true, get: functi
|
||||||
//# sourceMappingURL=core.js.map
|
//# sourceMappingURL=core.js.map
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 471 */,
|
/* 471 */
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const cache = __importStar(__webpack_require__(692));
|
||||||
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
const constants_1 = __webpack_require__(196);
|
||||||
|
const utils = __importStar(__webpack_require__(443));
|
||||||
|
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
||||||
|
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
|
||||||
|
// throw an uncaught exception. Instead of failing this action, just warn.
|
||||||
|
process.on("uncaughtException", e => utils.logWarning(e.message));
|
||||||
|
function saveImpl(stateProvider) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
try {
|
||||||
|
if (!utils.isCacheFeatureAvailable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If restore has stored a primary key in state, reuse that
|
||||||
|
// Else re-evaluate from inputs
|
||||||
|
const primaryKey = stateProvider.getState(constants_1.State.CachePrimaryKey) ||
|
||||||
|
core.getInput(constants_1.Inputs.Key);
|
||||||
|
if (!primaryKey) {
|
||||||
|
utils.logWarning(`Key is not specified.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If matched restore key is same as primary key, then do not save cache
|
||||||
|
// NO-OP in case of SaveOnly action
|
||||||
|
const restoredKey = stateProvider.getCacheState();
|
||||||
|
if (utils.isExactKeyMatch(primaryKey, restoredKey)) {
|
||||||
|
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
const cacheId = yield cache.saveCache(cachePaths, primaryKey, {
|
||||||
|
uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize)
|
||||||
|
});
|
||||||
|
if (cacheId != -1) {
|
||||||
|
core.info(`Cache saved with key: ${primaryKey}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
utils.logWarning(error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.default = saveImpl;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
/* 472 */,
|
/* 472 */,
|
||||||
/* 473 */,
|
/* 473 */,
|
||||||
/* 474 */,
|
/* 474 */,
|
||||||
|
|
@ -44133,318 +44334,7 @@ exports.default = _default;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 640 */
|
/* 640 */,
|
||||||
/***/ (function(module) {
|
|
||||||
|
|
||||||
/*! *****************************************************************************
|
|
||||||
Copyright (c) Microsoft Corporation.
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
***************************************************************************** */
|
|
||||||
/* global global, define, System, Reflect, Promise */
|
|
||||||
var __extends;
|
|
||||||
var __assign;
|
|
||||||
var __rest;
|
|
||||||
var __decorate;
|
|
||||||
var __param;
|
|
||||||
var __metadata;
|
|
||||||
var __awaiter;
|
|
||||||
var __generator;
|
|
||||||
var __exportStar;
|
|
||||||
var __values;
|
|
||||||
var __read;
|
|
||||||
var __spread;
|
|
||||||
var __spreadArrays;
|
|
||||||
var __spreadArray;
|
|
||||||
var __await;
|
|
||||||
var __asyncGenerator;
|
|
||||||
var __asyncDelegator;
|
|
||||||
var __asyncValues;
|
|
||||||
var __makeTemplateObject;
|
|
||||||
var __importStar;
|
|
||||||
var __importDefault;
|
|
||||||
var __classPrivateFieldGet;
|
|
||||||
var __classPrivateFieldSet;
|
|
||||||
var __createBinding;
|
|
||||||
(function (factory) {
|
|
||||||
var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
|
|
||||||
if (typeof define === "function" && define.amd) {
|
|
||||||
define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
|
|
||||||
}
|
|
||||||
else if ( true && typeof module.exports === "object") {
|
|
||||||
factory(createExporter(root, createExporter(module.exports)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
factory(createExporter(root));
|
|
||||||
}
|
|
||||||
function createExporter(exports, previous) {
|
|
||||||
if (exports !== root) {
|
|
||||||
if (typeof Object.create === "function") {
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
exports.__esModule = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
|
|
||||||
}
|
|
||||||
})
|
|
||||||
(function (exporter) {
|
|
||||||
var extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
|
|
||||||
__extends = function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
|
|
||||||
__assign = Object.assign || function (t) {
|
|
||||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
||||||
s = arguments[i];
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
|
|
||||||
__rest = function (s, e) {
|
|
||||||
var t = {};
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
||||||
t[p] = s[p];
|
|
||||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
||||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
||||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
||||||
t[p[i]] = s[p[i]];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
|
|
||||||
__decorate = function (decorators, target, key, desc) {
|
|
||||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
||||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
||||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
||||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
||||||
};
|
|
||||||
|
|
||||||
__param = function (paramIndex, decorator) {
|
|
||||||
return function (target, key) { decorator(target, key, paramIndex); }
|
|
||||||
};
|
|
||||||
|
|
||||||
__metadata = function (metadataKey, metadataValue) {
|
|
||||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
__awaiter = function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
__generator = function (thisArg, body) {
|
|
||||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
||||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
||||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
||||||
function step(op) {
|
|
||||||
if (f) throw new TypeError("Generator is already executing.");
|
|
||||||
while (_) try {
|
|
||||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
||||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
||||||
switch (op[0]) {
|
|
||||||
case 0: case 1: t = op; break;
|
|
||||||
case 4: _.label++; return { value: op[1], done: false };
|
|
||||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
||||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
||||||
default:
|
|
||||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
||||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
||||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
||||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
||||||
if (t[2]) _.ops.pop();
|
|
||||||
_.trys.pop(); continue;
|
|
||||||
}
|
|
||||||
op = body.call(thisArg, _);
|
|
||||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
||||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
__exportStar = function(m, o) {
|
|
||||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
|
|
||||||
};
|
|
||||||
|
|
||||||
__createBinding = Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
});
|
|
||||||
|
|
||||||
__values = function (o) {
|
|
||||||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
||||||
if (m) return m.call(o);
|
|
||||||
if (o && typeof o.length === "number") return {
|
|
||||||
next: function () {
|
|
||||||
if (o && i >= o.length) o = void 0;
|
|
||||||
return { value: o && o[i++], done: !o };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
||||||
};
|
|
||||||
|
|
||||||
__read = function (o, n) {
|
|
||||||
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
||||||
if (!m) return o;
|
|
||||||
var i = m.call(o), r, ar = [], e;
|
|
||||||
try {
|
|
||||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
||||||
}
|
|
||||||
catch (error) { e = { error: error }; }
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
||||||
}
|
|
||||||
finally { if (e) throw e.error; }
|
|
||||||
}
|
|
||||||
return ar;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
__spread = function () {
|
|
||||||
for (var ar = [], i = 0; i < arguments.length; i++)
|
|
||||||
ar = ar.concat(__read(arguments[i]));
|
|
||||||
return ar;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
__spreadArrays = function () {
|
|
||||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
||||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
||||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
||||||
r[k] = a[j];
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
|
|
||||||
__spreadArray = function (to, from, pack) {
|
|
||||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
||||||
if (ar || !(i in from)) {
|
|
||||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
||||||
ar[i] = from[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return to.concat(ar || Array.prototype.slice.call(from));
|
|
||||||
};
|
|
||||||
|
|
||||||
__await = function (v) {
|
|
||||||
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
||||||
};
|
|
||||||
|
|
||||||
__asyncGenerator = function (thisArg, _arguments, generator) {
|
|
||||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
||||||
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
||||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
||||||
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
||||||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
||||||
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
||||||
function fulfill(value) { resume("next", value); }
|
|
||||||
function reject(value) { resume("throw", value); }
|
|
||||||
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
||||||
};
|
|
||||||
|
|
||||||
__asyncDelegator = function (o) {
|
|
||||||
var i, p;
|
|
||||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
|
||||||
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
|
|
||||||
};
|
|
||||||
|
|
||||||
__asyncValues = function (o) {
|
|
||||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
||||||
var m = o[Symbol.asyncIterator], i;
|
|
||||||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
||||||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
||||||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
||||||
};
|
|
||||||
|
|
||||||
__makeTemplateObject = function (cooked, raw) {
|
|
||||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
||||||
return cooked;
|
|
||||||
};
|
|
||||||
|
|
||||||
var __setModuleDefault = Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
};
|
|
||||||
|
|
||||||
__importStar = function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
__importDefault = function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
|
|
||||||
__classPrivateFieldGet = function (receiver, state, kind, f) {
|
|
||||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
||||||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
||||||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
||||||
};
|
|
||||||
|
|
||||||
__classPrivateFieldSet = function (receiver, state, value, kind, f) {
|
|
||||||
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
||||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
||||||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
||||||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
||||||
};
|
|
||||||
|
|
||||||
exporter("__extends", __extends);
|
|
||||||
exporter("__assign", __assign);
|
|
||||||
exporter("__rest", __rest);
|
|
||||||
exporter("__decorate", __decorate);
|
|
||||||
exporter("__param", __param);
|
|
||||||
exporter("__metadata", __metadata);
|
|
||||||
exporter("__awaiter", __awaiter);
|
|
||||||
exporter("__generator", __generator);
|
|
||||||
exporter("__exportStar", __exportStar);
|
|
||||||
exporter("__createBinding", __createBinding);
|
|
||||||
exporter("__values", __values);
|
|
||||||
exporter("__read", __read);
|
|
||||||
exporter("__spread", __spread);
|
|
||||||
exporter("__spreadArrays", __spreadArrays);
|
|
||||||
exporter("__spreadArray", __spreadArray);
|
|
||||||
exporter("__await", __await);
|
|
||||||
exporter("__asyncGenerator", __asyncGenerator);
|
|
||||||
exporter("__asyncDelegator", __asyncDelegator);
|
|
||||||
exporter("__asyncValues", __asyncValues);
|
|
||||||
exporter("__makeTemplateObject", __makeTemplateObject);
|
|
||||||
exporter("__importStar", __importStar);
|
|
||||||
exporter("__importDefault", __importDefault);
|
|
||||||
exporter("__classPrivateFieldGet", __classPrivateFieldGet);
|
|
||||||
exporter("__classPrivateFieldSet", __classPrivateFieldSet);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
/* 641 */,
|
/* 641 */,
|
||||||
/* 642 */,
|
/* 642 */,
|
||||||
/* 643 */,
|
/* 643 */,
|
||||||
|
|
@ -47275,29 +47165,6 @@ exports.default = _default;
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
||||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
||||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
||||||
}
|
|
||||||
Object.defineProperty(o, k2, desc);
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
|
@ -47307,49 +47174,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const cache = __importStar(__webpack_require__(692));
|
const saveImpl_1 = __importDefault(__webpack_require__(471));
|
||||||
const core = __importStar(__webpack_require__(470));
|
const stateProvider_1 = __webpack_require__(309);
|
||||||
const constants_1 = __webpack_require__(196);
|
|
||||||
const utils = __importStar(__webpack_require__(443));
|
|
||||||
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
|
||||||
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
|
|
||||||
// throw an uncaught exception. Instead of failing this action, just warn.
|
|
||||||
process.on("uncaughtException", e => utils.logWarning(e.message));
|
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
yield (0, saveImpl_1.default)(new stateProvider_1.StateProvider());
|
||||||
if (!utils.isCacheFeatureAvailable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const state = utils.getCacheState();
|
|
||||||
// Inputs are re-evaluted before the post action, so we want the original key used for restore
|
|
||||||
const primaryKey = core.getState(constants_1.State.CachePrimaryKey) || core.getInput(constants_1.Inputs.Key);
|
|
||||||
if (!primaryKey) {
|
|
||||||
utils.logWarning(`Error retrieving key from state.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (utils.isExactKeyMatch(primaryKey, state)) {
|
|
||||||
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
|
|
||||||
required: true
|
|
||||||
});
|
|
||||||
const cacheId = yield cache.saveCache(cachePaths, primaryKey, {
|
|
||||||
uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize)
|
|
||||||
});
|
|
||||||
if (cacheId != -1) {
|
|
||||||
core.info(`Cache saved with key: ${primaryKey}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
utils.logWarning(error.message);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
run();
|
run();
|
||||||
|
|
@ -47422,6 +47255,7 @@ const path = __importStar(__webpack_require__(622));
|
||||||
const utils = __importStar(__webpack_require__(15));
|
const utils = __importStar(__webpack_require__(15));
|
||||||
const cacheHttpClient = __importStar(__webpack_require__(114));
|
const cacheHttpClient = __importStar(__webpack_require__(114));
|
||||||
const tar_1 = __webpack_require__(434);
|
const tar_1 = __webpack_require__(434);
|
||||||
|
const constants_1 = __webpack_require__(931);
|
||||||
class ValidationError extends Error {
|
class ValidationError extends Error {
|
||||||
constructor(message) {
|
constructor(message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
@ -47483,13 +47317,33 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
checkKey(key);
|
checkKey(key);
|
||||||
}
|
}
|
||||||
const compressionMethod = yield utils.getCompressionMethod();
|
let cacheEntry;
|
||||||
|
let compressionMethod = yield utils.getCompressionMethod();
|
||||||
let archivePath = '';
|
let archivePath = '';
|
||||||
try {
|
try {
|
||||||
// path are needed to compute version
|
try {
|
||||||
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
// path are needed to compute version
|
||||||
compressionMethod
|
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||||
});
|
compressionMethod
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
// This is to support the old cache entry created
|
||||||
|
// by the old version of the cache action on windows.
|
||||||
|
if (process.platform === 'win32' &&
|
||||||
|
compressionMethod !== constants_1.CompressionMethod.Gzip) {
|
||||||
|
compressionMethod = constants_1.CompressionMethod.Gzip;
|
||||||
|
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||||
|
compressionMethod
|
||||||
|
});
|
||||||
|
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||||
// Cache not found
|
// Cache not found
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -53495,6 +53349,11 @@ var CompressionMethod;
|
||||||
CompressionMethod["ZstdWithoutLong"] = "zstd-without-long";
|
CompressionMethod["ZstdWithoutLong"] = "zstd-without-long";
|
||||||
CompressionMethod["Zstd"] = "zstd";
|
CompressionMethod["Zstd"] = "zstd";
|
||||||
})(CompressionMethod = exports.CompressionMethod || (exports.CompressionMethod = {}));
|
})(CompressionMethod = exports.CompressionMethod || (exports.CompressionMethod = {}));
|
||||||
|
var ArchiveToolType;
|
||||||
|
(function (ArchiveToolType) {
|
||||||
|
ArchiveToolType["GNU"] = "gnu";
|
||||||
|
ArchiveToolType["BSD"] = "bsd";
|
||||||
|
})(ArchiveToolType = exports.ArchiveToolType || (exports.ArchiveToolType = {}));
|
||||||
// The default number of retry attempts.
|
// The default number of retry attempts.
|
||||||
exports.DefaultRetryAttempts = 2;
|
exports.DefaultRetryAttempts = 2;
|
||||||
// The default delay in milliseconds between retry attempts.
|
// The default delay in milliseconds between retry attempts.
|
||||||
|
|
@ -53503,6 +53362,12 @@ exports.DefaultRetryDelay = 5000;
|
||||||
// over the socket during this period, the socket is destroyed and the download
|
// over the socket during this period, the socket is destroyed and the download
|
||||||
// is aborted.
|
// is aborted.
|
||||||
exports.SocketTimeout = 5000;
|
exports.SocketTimeout = 5000;
|
||||||
|
// The default path of GNUtar on hosted Windows runners
|
||||||
|
exports.GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`;
|
||||||
|
// The default path of BSDtar on hosted Windows runners
|
||||||
|
exports.SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`;
|
||||||
|
exports.TarFilename = 'cache.tar';
|
||||||
|
exports.ManifestFilename = 'manifest.txt';
|
||||||
//# sourceMappingURL=constants.js.map
|
//# sourceMappingURL=constants.js.map
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
|
||||||
21
examples.md
21
examples.md
|
|
@ -309,14 +309,29 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
|
||||||
For npm, cache files are stored in `~/.npm` on Posix, or `~\AppData\npm-cache` on Windows, but it's possible to use `npm config get cache` to find the path on any platform. See [the npm docs](https://docs.npmjs.com/cli/cache#cache) for more details.
|
For npm, cache files are stored in `~/.npm` on Posix, or `~\AppData\npm-cache` on Windows, but it's possible to use `npm config get cache` to find the path on any platform. See [the npm docs](https://docs.npmjs.com/cli/cache#cache) for more details.
|
||||||
|
|
||||||
If using `npm config` to retrieve the cache directory, ensure you run [actions/setup-node](https://github.com/actions/setup-node) first to ensure your `npm` version is correct.
|
If using `npm config` to retrieve the cache directory, ensure you run [actions/setup-node](https://github.com/actions/setup-node) first to ensure your `npm` version is correct.
|
||||||
|
After [deprecation](https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/) of save-state and set-output commands, the correct way to set output is using `${GITHUB_OUTPUT}`. For linux, we can use `${GITHUB_OUTPUT}` whereas for windows we need to use `${env:GITHUB_OUTPUT}` due to two different default shells in these two different OS ie `bash` and `pwsh` respectively.
|
||||||
|
|
||||||
>Note: It is not recommended to cache `node_modules`, as it can break across Node versions and won't work with `npm ci`
|
>Note: It is not recommended to cache `node_modules`, as it can break across Node versions and won't work with `npm ci`
|
||||||
|
|
||||||
|
### **Get npm cache directory using same shell**
|
||||||
|
### Bash shell
|
||||||
```yaml
|
```yaml
|
||||||
- name: Get npm cache directory
|
- name: Get npm cache directory
|
||||||
id: npm-cache-dir
|
id: npm-cache
|
||||||
run: |
|
shell: bash
|
||||||
echo "::set-output name=dir::$(npm config get cache)"
|
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
|
||||||
|
```
|
||||||
|
|
||||||
|
### PWSH shell
|
||||||
|
```yaml
|
||||||
|
- name: Get npm cache directory
|
||||||
|
id: npm-cache
|
||||||
|
shell: pwsh
|
||||||
|
run: echo "dir=$(npm config get cache)" >> ${env:GITHUB_OUTPUT}
|
||||||
|
```
|
||||||
|
`Get npm cache directory` step can then be used with `actions/cache` as shown below
|
||||||
|
|
||||||
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
|
id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"version": "3.0.11",
|
"version": "3.1.0-beta.2",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"version": "3.0.11",
|
"version": "3.1.0-beta.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^3.0.5",
|
"@actions/cache": "3.1.0-beta.2",
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/io": "^1.1.2"
|
"@actions/io": "^1.1.2"
|
||||||
|
|
@ -36,15 +36,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/cache": {
|
"node_modules/@actions/cache": {
|
||||||
"version": "3.0.5",
|
"version": "3.1.0-beta.2",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.1.0-beta.2.tgz",
|
||||||
"integrity": "sha512-0WpPmwnRPkn5k5ASmjoX8bY8NrZEPTwN+64nGYJmR/bHjEVgC8svdf5K956wi67tNJBGJky2+UfvNbUOtHmMHg==",
|
"integrity": "sha512-xt9NLWPCh5WU9Z5ITeGpT5Nza/57wMXeLsGuNVcRCIVpPuNTf3Puj82vjZZQw4rGqiCCs+n4+hnkTcE9BKw2sw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.0.1",
|
"@actions/exec": "^1.0.1",
|
||||||
"@actions/glob": "^0.1.0",
|
"@actions/glob": "^0.1.0",
|
||||||
"@actions/http-client": "^2.0.1",
|
"@actions/http-client": "^2.0.1",
|
||||||
"@actions/io": "^1.0.1",
|
"@actions/io": "^1.0.1",
|
||||||
|
"@azure/abort-controller": "^1.1.0",
|
||||||
"@azure/ms-rest-js": "^2.6.0",
|
"@azure/ms-rest-js": "^2.6.0",
|
||||||
"@azure/storage-blob": "^12.8.0",
|
"@azure/storage-blob": "^12.8.0",
|
||||||
"semver": "^6.1.0",
|
"semver": "^6.1.0",
|
||||||
|
|
@ -111,14 +112,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/abort-controller": {
|
"node_modules/@azure/abort-controller": {
|
||||||
"version": "1.0.4",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz",
|
||||||
"integrity": "sha512-lNUmDRVGpanCsiUN3NWxFTdwmdFI53xwhkTFfHDGTYk46ca7Ind3nanJc+U6Zj9Tv+9nTCWRBscWEW1DyKOpTw==",
|
"integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.0.0"
|
"tslib": "^2.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0.0"
|
"node": ">=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/abort-controller/node_modules/tslib": {
|
"node_modules/@azure/abort-controller/node_modules/tslib": {
|
||||||
|
|
@ -9721,15 +9722,16 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": {
|
"@actions/cache": {
|
||||||
"version": "3.0.5",
|
"version": "3.1.0-beta.2",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.1.0-beta.2.tgz",
|
||||||
"integrity": "sha512-0WpPmwnRPkn5k5ASmjoX8bY8NrZEPTwN+64nGYJmR/bHjEVgC8svdf5K956wi67tNJBGJky2+UfvNbUOtHmMHg==",
|
"integrity": "sha512-xt9NLWPCh5WU9Z5ITeGpT5Nza/57wMXeLsGuNVcRCIVpPuNTf3Puj82vjZZQw4rGqiCCs+n4+hnkTcE9BKw2sw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.0.1",
|
"@actions/exec": "^1.0.1",
|
||||||
"@actions/glob": "^0.1.0",
|
"@actions/glob": "^0.1.0",
|
||||||
"@actions/http-client": "^2.0.1",
|
"@actions/http-client": "^2.0.1",
|
||||||
"@actions/io": "^1.0.1",
|
"@actions/io": "^1.0.1",
|
||||||
|
"@azure/abort-controller": "^1.1.0",
|
||||||
"@azure/ms-rest-js": "^2.6.0",
|
"@azure/ms-rest-js": "^2.6.0",
|
||||||
"@azure/storage-blob": "^12.8.0",
|
"@azure/storage-blob": "^12.8.0",
|
||||||
"semver": "^6.1.0",
|
"semver": "^6.1.0",
|
||||||
|
|
@ -9792,11 +9794,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@azure/abort-controller": {
|
"@azure/abort-controller": {
|
||||||
"version": "1.0.4",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz",
|
||||||
"integrity": "sha512-lNUmDRVGpanCsiUN3NWxFTdwmdFI53xwhkTFfHDGTYk46ca7Ind3nanJc+U6Zj9Tv+9nTCWRBscWEW1DyKOpTw==",
|
"integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^2.0.0"
|
"tslib": "^2.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": {
|
"tslib": {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"version": "3.0.11",
|
"version": "3.1.0-beta.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Cache dependencies and build outputs",
|
"description": "Cache dependencies and build outputs",
|
||||||
"main": "dist/restore/index.js",
|
"main": "dist/restore/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc && ncc build -o dist/restore src/restore.ts && ncc build -o dist/save src/save.ts",
|
"build": "tsc && ncc build -o dist/restore src/restore.ts && ncc build -o dist/save src/save.ts && ncc build -o dist/restore-only src/restoreOnly.ts && ncc build -o dist/save-only src/saveOnly.ts",
|
||||||
"test": "tsc --noEmit && jest --coverage",
|
"test": "tsc --noEmit && jest --coverage",
|
||||||
"lint": "eslint **/*.ts --cache",
|
"lint": "eslint **/*.ts --cache",
|
||||||
"format": "prettier --write **/*.ts",
|
"format": "prettier --write **/*.ts",
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^3.0.5",
|
"@actions/cache": "3.1.0-beta.2",
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/io": "^1.1.2"
|
"@actions/io": "^1.1.2"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: 'Restore Cache'
|
name: 'Restore Only Cache'
|
||||||
description: 'Restore Cache artifacts like dependencies and build outputs to improve workflow execution time'
|
description: 'Restore Cache artifacts like dependencies and build outputs to improve workflow execution time'
|
||||||
author: 'GitHub'
|
author: 'GitHub'
|
||||||
inputs:
|
inputs:
|
||||||
|
|
@ -11,17 +11,16 @@ inputs:
|
||||||
restore-keys:
|
restore-keys:
|
||||||
description: 'An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
|
description: 'An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
|
||||||
required: false
|
required: false
|
||||||
exit-on-cache-miss:
|
|
||||||
description: 'Fail the workflow if the cache is not found for the primary key'
|
|
||||||
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'
|
||||||
|
cache-primary-key:
|
||||||
|
description: 'Cache primary key passed in the input to use in subsequent steps of the workflow'
|
||||||
|
cache-restore-key:
|
||||||
|
description: 'Cache key restored'
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node16'
|
||||||
main: '../dist/restore/index.js'
|
main: '../dist/restore-only/index.js'
|
||||||
branding:
|
branding:
|
||||||
icon: 'archive'
|
icon: 'archive'
|
||||||
color: 'gray-dark'
|
color: 'gray-dark'
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: 'Save Cache'
|
name: 'Save Only Cache'
|
||||||
description: 'Save Cache artifacts like dependencies and build outputs to improve workflow execution time'
|
description: 'Save Cache artifacts like dependencies and build outputs to improve workflow execution time'
|
||||||
author: 'GitHub'
|
author: 'GitHub'
|
||||||
inputs:
|
inputs:
|
||||||
|
|
@ -13,7 +13,7 @@ inputs:
|
||||||
required: false
|
required: false
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node16'
|
||||||
main: '../dist/save/index.js'
|
main: '../dist/save-only/index.js'
|
||||||
branding:
|
branding:
|
||||||
icon: 'archive'
|
icon: 'archive'
|
||||||
color: 'gray-dark'
|
color: 'gray-dark'
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
export enum Inputs {
|
export enum Inputs {
|
||||||
Key = "key",
|
Key = "key", // Input for cache, restore, save action
|
||||||
Path = "path",
|
Path = "path", // Input for cache, restore, save action
|
||||||
RestoreKeys = "restore-keys",
|
RestoreKeys = "restore-keys", // Input for cache, restore action
|
||||||
UploadChunkSize = "upload-chunk-size",
|
UploadChunkSize = "upload-chunk-size" // Input for cache, save action
|
||||||
FailOnCacheMiss = "fail-on-cache-miss",
|
|
||||||
SaveOnAnyFailure = "save-on-any-failure"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Outputs {
|
export enum Outputs {
|
||||||
CacheHit = "cache-hit"
|
CacheHit = "cache-hit", // Output from cache, restore action
|
||||||
|
CachePrimaryKey = "cache-primary-key", // Output from restore action
|
||||||
|
CacheRestoreKey = "cache-restore-key" // Output from restore action
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum State {
|
export enum State {
|
||||||
|
|
@ -22,8 +22,4 @@ export enum Events {
|
||||||
PullRequest = "pull_request"
|
PullRequest = "pull_request"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Variables {
|
|
||||||
SaveCacheOnAnyFailure = "SAVE_CACHE_ON_ANY_FAILURE"
|
|
||||||
}
|
|
||||||
|
|
||||||
export const RefKey = "GITHUB_REF";
|
export const RefKey = "GITHUB_REF";
|
||||||
|
|
|
||||||
|
|
@ -1,84 +1,8 @@
|
||||||
import * as cache from "@actions/cache";
|
import restoreImpl from "./restoreImpl";
|
||||||
import * as core from "@actions/core";
|
import { StateProvider } from "./stateProvider";
|
||||||
|
|
||||||
import { Events, Inputs, State, Variables } from "./constants";
|
|
||||||
import * as utils from "./utils/actionUtils";
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
try {
|
await restoreImpl(new StateProvider());
|
||||||
if (!utils.isCacheFeatureAvailable()) {
|
|
||||||
utils.setCacheHitOutput(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate inputs, this can cause task failure
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(
|
|
||||||
`Event Validation Error: The event type ${
|
|
||||||
process.env[Events.Key]
|
|
||||||
} is not supported because it's not tied to a branch or tag ref.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const primaryKey = core.getInput(Inputs.Key, { required: true });
|
|
||||||
core.saveState(State.CachePrimaryKey, primaryKey);
|
|
||||||
|
|
||||||
const restoreKeys = utils.getInputAsArray(Inputs.RestoreKeys);
|
|
||||||
const cachePaths = utils.getInputAsArray(Inputs.Path, {
|
|
||||||
required: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const cacheKey = await cache.restoreCache(
|
|
||||||
cachePaths,
|
|
||||||
primaryKey,
|
|
||||||
restoreKeys
|
|
||||||
);
|
|
||||||
|
|
||||||
//Check if user wants to save cache despite of failure in any previous job
|
|
||||||
const saveCache = core.getInput(Inputs.SaveOnAnyFailure).toLowerCase();
|
|
||||||
if (saveCache == "true") {
|
|
||||||
core.debug(
|
|
||||||
`Exporting environment variable ${Variables.SaveCacheOnAnyFailure}`
|
|
||||||
);
|
|
||||||
core.exportVariable(Variables.SaveCacheOnAnyFailure, saveCache);
|
|
||||||
core.info(
|
|
||||||
`Input Variable ${Variables.SaveCacheOnAnyFailure} is set to true, the cache will be saved despite of any failure in the build.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cacheKey) {
|
|
||||||
if (core.getInput(Inputs.FailOnCacheMiss).toLowerCase() == "true") {
|
|
||||||
throw new Error(
|
|
||||||
`Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the fail-on-cache-miss requirement is not met.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
core.info(
|
|
||||||
`Cache not found for input keys: ${[
|
|
||||||
primaryKey,
|
|
||||||
...restoreKeys
|
|
||||||
].join(", ")}`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Store the matched cache key
|
|
||||||
utils.setCacheState(cacheKey);
|
|
||||||
|
|
||||||
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
|
|
||||||
utils.setCacheHitOutput(isExactKeyMatch);
|
|
||||||
|
|
||||||
if (
|
|
||||||
!isExactKeyMatch &&
|
|
||||||
core.getBooleanInput(Inputs.FailOnCacheMiss) == true
|
|
||||||
) {
|
|
||||||
throw new Error(
|
|
||||||
`Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the fail-on-cache-miss requirement is not met.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
core.info(`Cache restored from key: ${cacheKey}`);
|
|
||||||
} catch (error: unknown) {
|
|
||||||
core.setFailed((error as Error).message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
import * as cache from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Events, Inputs, Outputs, State } from "./constants";
|
||||||
|
import { IStateProvider } from "./stateProvider";
|
||||||
|
import * as utils from "./utils/actionUtils";
|
||||||
|
|
||||||
|
async function restoreImpl(
|
||||||
|
stateProvider: IStateProvider
|
||||||
|
): Promise<string | undefined> {
|
||||||
|
try {
|
||||||
|
if (!utils.isCacheFeatureAvailable()) {
|
||||||
|
utils.setCacheHitOutput(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate inputs, this can cause task failure
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(
|
||||||
|
`Event Validation Error: The event type ${
|
||||||
|
process.env[Events.Key]
|
||||||
|
} is not supported because it's not tied to a branch or tag ref.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const primaryKey = core.getInput(Inputs.Key, { required: true });
|
||||||
|
stateProvider.setState(State.CachePrimaryKey, primaryKey);
|
||||||
|
|
||||||
|
const restoreKeys = utils.getInputAsArray(Inputs.RestoreKeys);
|
||||||
|
const cachePaths = utils.getInputAsArray(Inputs.Path, {
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const cacheKey = await cache.restoreCache(
|
||||||
|
cachePaths,
|
||||||
|
primaryKey,
|
||||||
|
restoreKeys
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!cacheKey) {
|
||||||
|
core.info(
|
||||||
|
`Cache not found for input keys: ${[
|
||||||
|
primaryKey,
|
||||||
|
...restoreKeys
|
||||||
|
].join(", ")}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the matched cache key in states
|
||||||
|
stateProvider.setState(State.CacheMatchedKey, cacheKey);
|
||||||
|
|
||||||
|
const isExactKeyMatch = utils.isExactKeyMatch(
|
||||||
|
core.getInput(Inputs.Key, { required: true }),
|
||||||
|
cacheKey
|
||||||
|
);
|
||||||
|
|
||||||
|
core.setOutput(Outputs.CacheHit, isExactKeyMatch.toString());
|
||||||
|
core.info(`Cache restored from key: ${cacheKey}`);
|
||||||
|
|
||||||
|
return cacheKey;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
core.setFailed((error as Error).message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default restoreImpl;
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import restoreImpl from "./restoreImpl";
|
||||||
|
import { NullStateProvider } from "./stateProvider";
|
||||||
|
|
||||||
|
async function run(): Promise<void> {
|
||||||
|
await restoreImpl(new NullStateProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
|
|
||||||
|
export default run;
|
||||||
59
src/save.ts
59
src/save.ts
|
|
@ -1,61 +1,8 @@
|
||||||
import * as cache from "@actions/cache";
|
import saveImpl from "./saveImpl";
|
||||||
import * as core from "@actions/core";
|
import { StateProvider } from "./stateProvider";
|
||||||
|
|
||||||
import { Events, Inputs, State } from "./constants";
|
|
||||||
import * as utils from "./utils/actionUtils";
|
|
||||||
|
|
||||||
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
|
||||||
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
|
|
||||||
// throw an uncaught exception. Instead of failing this action, just warn.
|
|
||||||
process.on("uncaughtException", e => utils.logWarning(e.message));
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
try {
|
await saveImpl(new StateProvider());
|
||||||
if (!utils.isCacheFeatureAvailable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(
|
|
||||||
`Event Validation Error: The event type ${
|
|
||||||
process.env[Events.Key]
|
|
||||||
} is not supported because it's not tied to a branch or tag ref.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const state = utils.getCacheState();
|
|
||||||
|
|
||||||
// Inputs are re-evaluted before the post action, so we want the original key used for restore
|
|
||||||
const primaryKey =
|
|
||||||
core.getState(State.CachePrimaryKey) || core.getInput(Inputs.Key);
|
|
||||||
|
|
||||||
if (!primaryKey) {
|
|
||||||
utils.logWarning(`Error retrieving key from state.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utils.isExactKeyMatch(primaryKey, state)) {
|
|
||||||
core.info(
|
|
||||||
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cachePaths = utils.getInputAsArray(Inputs.Path, {
|
|
||||||
required: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const cacheId = await cache.saveCache(cachePaths, primaryKey, {
|
|
||||||
uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cacheId != -1) {
|
|
||||||
core.info(`Cache saved with key: ${primaryKey}`);
|
|
||||||
}
|
|
||||||
} catch (error: unknown) {
|
|
||||||
utils.logWarning((error as Error).message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import * as cache from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Events, Inputs, State } from "./constants";
|
||||||
|
import { IStateProvider } from "./stateProvider";
|
||||||
|
import * as utils from "./utils/actionUtils";
|
||||||
|
|
||||||
|
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
||||||
|
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
|
||||||
|
// throw an uncaught exception. Instead of failing this action, just warn.
|
||||||
|
process.on("uncaughtException", e => utils.logWarning(e.message));
|
||||||
|
|
||||||
|
async function saveImpl(stateProvider: IStateProvider): Promise<void> {
|
||||||
|
try {
|
||||||
|
if (!utils.isCacheFeatureAvailable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(
|
||||||
|
`Event Validation Error: The event type ${
|
||||||
|
process.env[Events.Key]
|
||||||
|
} is not supported because it's not tied to a branch or tag ref.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If restore has stored a primary key in state, reuse that
|
||||||
|
// Else re-evaluate from inputs
|
||||||
|
const primaryKey =
|
||||||
|
stateProvider.getState(State.CachePrimaryKey) ||
|
||||||
|
core.getInput(Inputs.Key);
|
||||||
|
|
||||||
|
if (!primaryKey) {
|
||||||
|
utils.logWarning(`Key is not specified.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If matched restore key is same as primary key, then do not save cache
|
||||||
|
// NO-OP in case of SaveOnly action
|
||||||
|
const restoredKey = stateProvider.getCacheState();
|
||||||
|
|
||||||
|
if (utils.isExactKeyMatch(primaryKey, restoredKey)) {
|
||||||
|
core.info(
|
||||||
|
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachePaths = utils.getInputAsArray(Inputs.Path, {
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const cacheId = await cache.saveCache(cachePaths, primaryKey, {
|
||||||
|
uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cacheId != -1) {
|
||||||
|
core.info(`Cache saved with key: ${primaryKey}`);
|
||||||
|
}
|
||||||
|
} catch (error: unknown) {
|
||||||
|
utils.logWarning((error as Error).message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default saveImpl;
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import saveImpl from "./saveImpl";
|
||||||
|
import { NullStateProvider } from "./stateProvider";
|
||||||
|
|
||||||
|
async function run(): Promise<void> {
|
||||||
|
await saveImpl(new NullStateProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
|
|
||||||
|
export default run;
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
import { Outputs, State } from "./constants";
|
||||||
|
|
||||||
|
export interface IStateProvider {
|
||||||
|
setState(key: string, value: string): void;
|
||||||
|
getState(key: string): string;
|
||||||
|
|
||||||
|
getCacheState(): string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StateProviderBase implements IStateProvider {
|
||||||
|
getCacheState(): string | undefined {
|
||||||
|
const cacheKey = this.getState(State.CacheMatchedKey);
|
||||||
|
if (cacheKey) {
|
||||||
|
core.debug(`Cache state/key: ${cacheKey}`);
|
||||||
|
return cacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
||||||
|
setState = (key: string, value: string) => {};
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
getState = (key: string) => "";
|
||||||
|
}
|
||||||
|
|
||||||
|
export class StateProvider extends StateProviderBase {
|
||||||
|
setState = core.saveState;
|
||||||
|
getState = core.getState;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NullStateProvider extends StateProviderBase {
|
||||||
|
stateToOutputMap = new Map<string, string>([
|
||||||
|
[State.CacheMatchedKey, Outputs.CacheRestoreKey],
|
||||||
|
[State.CachePrimaryKey, Outputs.CachePrimaryKey]
|
||||||
|
]);
|
||||||
|
|
||||||
|
setState = (key: string, value: string) => {
|
||||||
|
core.setOutput(this.stateToOutputMap.get(key) as string, value);
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
getState = (key: string) => "";
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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 { Outputs, RefKey, State } from "../constants";
|
import { Outputs, RefKey } from "../constants";
|
||||||
|
|
||||||
export function isGhes(): boolean {
|
export function isGhes(): boolean {
|
||||||
const ghUrl = new URL(
|
const ghUrl = new URL(
|
||||||
|
|
@ -19,30 +19,10 @@ export function isExactKeyMatch(key: string, cacheKey?: string): boolean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setCacheState(state: string): void {
|
|
||||||
core.saveState(State.CacheMatchedKey, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setCacheHitOutput(isCacheHit: boolean): void {
|
export function setCacheHitOutput(isCacheHit: boolean): void {
|
||||||
core.setOutput(Outputs.CacheHit, isCacheHit.toString());
|
core.setOutput(Outputs.CacheHit, isCacheHit.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setOutputAndState(key: string, cacheKey?: string): void {
|
|
||||||
setCacheHitOutput(isExactKeyMatch(key, cacheKey));
|
|
||||||
// Store the matched cache key if it exists
|
|
||||||
cacheKey && setCacheState(cacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCacheState(): string | undefined {
|
|
||||||
const cacheKey = core.getState(State.CacheMatchedKey);
|
|
||||||
if (cacheKey) {
|
|
||||||
core.debug(`Cache state/key: ${cacheKey}`);
|
|
||||||
return cacheKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
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}`);
|
||||||
|
|
@ -77,19 +57,20 @@ export function getInputAsInt(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isCacheFeatureAvailable(): boolean {
|
export function isCacheFeatureAvailable(): boolean {
|
||||||
if (!cache.isFeatureAvailable()) {
|
if (cache.isFeatureAvailable()) {
|
||||||
if (isGhes()) {
|
return true;
|
||||||
logWarning(
|
}
|
||||||
`Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.
|
|
||||||
|
if (isGhes()) {
|
||||||
|
logWarning(
|
||||||
|
`Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.
|
||||||
Otherwise please upgrade to GHES version >= 3.5 and If you are also using Github Connect, please unretire the actions/cache namespace before upgrade (see https://docs.github.com/en/enterprise-server@3.5/admin/github-actions/managing-access-to-actions-from-githubcom/enabling-automatic-access-to-githubcom-actions-using-github-connect#automatic-retirement-of-namespaces-for-actions-accessed-on-githubcom)`
|
Otherwise please upgrade to GHES version >= 3.5 and If you are also using Github Connect, please unretire the actions/cache namespace before upgrade (see https://docs.github.com/en/enterprise-server@3.5/admin/github-actions/managing-access-to-actions-from-githubcom/enabling-automatic-access-to-githubcom-actions-using-github-connect#automatic-retirement-of-namespaces-for-actions-accessed-on-githubcom)`
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
logWarning(
|
|
||||||
"An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
logWarning(
|
||||||
|
"An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions."
|
||||||
|
);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,28 +13,18 @@ interface CacheInput {
|
||||||
path: string;
|
path: string;
|
||||||
key: string;
|
key: string;
|
||||||
restoreKeys?: string[];
|
restoreKeys?: string[];
|
||||||
failOnCacheMiss?: boolean;
|
|
||||||
saveOnAnyFailure?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setInputs(input: CacheInput): void {
|
export function setInputs(input: CacheInput): void {
|
||||||
setInput(Inputs.Path, input.path);
|
setInput(Inputs.Path, input.path);
|
||||||
setInput(Inputs.Key, input.key);
|
setInput(Inputs.Key, input.key);
|
||||||
setInput(Inputs.SaveOnAnyFailure, "false");
|
|
||||||
setInput(Inputs.FailOnCacheMiss, "false");
|
|
||||||
input.restoreKeys &&
|
input.restoreKeys &&
|
||||||
setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
|
setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
|
||||||
input.failOnCacheMiss &&
|
|
||||||
setInput(Inputs.FailOnCacheMiss, String(input.failOnCacheMiss));
|
|
||||||
input.saveOnAnyFailure &&
|
|
||||||
setInput(Inputs.SaveOnAnyFailure, String(input.saveOnAnyFailure));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearInputs(): void {
|
export function clearInputs(): void {
|
||||||
delete process.env[getInputName(Inputs.Path)];
|
delete process.env[getInputName(Inputs.Path)];
|
||||||
delete process.env[getInputName(Inputs.Key)];
|
delete process.env[getInputName(Inputs.Key)];
|
||||||
delete process.env[getInputName(Inputs.RestoreKeys)];
|
delete process.env[getInputName(Inputs.RestoreKeys)];
|
||||||
delete process.env[getInputName(Inputs.FailOnCacheMiss)];
|
|
||||||
delete process.env[getInputName(Inputs.SaveOnAnyFailure)];
|
|
||||||
delete process.env[getInputName(Inputs.UploadChunkSize)];
|
delete process.env[getInputName(Inputs.UploadChunkSize)];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue