Compare commits

..

99 Commits

Author SHA1 Message Date
ed5e94a5f5 Merge pull request #1006 from actions/700-actionscache-granular-cache-control
Actions Cache Granular Control Implementation
2022-12-15 16:22:14 +05:30
6277f55919 Updated beta version to 3.2.0-beta.1 2022-12-15 10:11:38 +00:00
c30e6dcb11 Merge pull request #1017 from actions/kotewar/readme-updates-for-granular-control
Readme updates for granular control
2022-12-15 14:38:13 +05:30
05c9b49ea4 nit: added language to code blocks 2022-12-15 09:05:17 +00:00
da311f75a6 nit 2022-12-15 09:01:49 +00:00
7a139a9cec Addressed review comments 2022-12-15 08:59:40 +00:00
930f080bad Added test case for restore state 2022-12-15 04:12:52 +00:00
56e956426f Repositioned new actions introduction 2022-12-14 18:49:43 +00:00
766d8255cd Removed verbose statements 2022-12-14 18:46:21 +00:00
686bf424a8 Update save/README.md
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-15 00:07:16 +05:30
fb5b333162 Update save/README.md
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-15 00:07:06 +05:30
c11ac6c2fe Update restore/README.md
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-15 00:06:56 +05:30
d5c949690c Update restore/README.md
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-15 00:06:41 +05:30
44df5ab77e Update restore/README.md
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-15 00:06:10 +05:30
65057ce6fe Added cache hit info in readme 2022-12-14 10:23:32 +00:00
8031e403b4 Merge remote-tracking branch 'origin/700-actionscache-granular-cache-control' into kotewar/readme-updates-for-granular-control 2022-12-14 10:19:50 +00:00
c8d01facfc Renamed output 2022-12-14 09:17:49 +00:00
81aaae062b Updates to save readme 2022-12-14 04:40:58 +00:00
9d445b2565 Added save readme 2022-12-14 04:35:02 +00:00
adecab4b4a Merge remote-tracking branch 'origin/700-actionscache-granular-cache-control' into kotewar/readme-updates-for-granular-control 2022-12-12 14:22:14 +00:00
075ad790b0 Merged beta branch and resolved conflicts 2022-12-12 14:18:42 +00:00
b275c83bd6 Merge remote-tracking branch 'origin/releases/v3-beta' into 700-actionscache-granular-cache-control 2022-12-12 14:18:23 +00:00
1ddc49105d Removed unused code 2022-12-12 14:03:16 +00:00
407044787b Added more assertions as values can't be checked 2022-12-12 13:50:54 +00:00
87a7d01109 Update restore/action.yml
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-12 18:50:18 +05:30
29d6c7aa7f Update restore/action.yml
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-12 18:50:09 +05:30
df53d3c04b Update restore/action.yml
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-12 18:49:59 +05:30
dd740c87de Update restore/action.yml
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-12 18:49:53 +05:30
0a6e5b052a Update save/action.yml
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-12 18:49:45 +05:30
a2137c625c update for new beta release 2022-12-12 13:01:08 +00:00
5a2b5e5714 Add support for gzip fallback for restore of old cache on windows 2022-12-12 12:57:44 +00:00
9e9a19bf5f Update dist folder 2022-12-12 12:57:44 +00:00
84ea3e177d Changes for beta release 2022-12-12 12:57:43 +00:00
00b72c7e02 Updated outputs of restore action 2022-12-12 11:36:12 +00:00
0cc9c1d4e8 Merge remote-tracking branch 'origin/700-actionscache-granular-cache-control' into kotewar/readme-updates-for-granular-control 2022-12-12 11:33:04 +00:00
ccf90c02ed Fixed breaking test case 2022-12-12 10:01:21 +00:00
4f42dc56c1 Added stateprovider test cases 2022-12-12 09:53:50 +00:00
b6604364ae Deleted stateprovider tests until added 2022-12-12 07:28:47 +00:00
c0cc8dd60a added stateprovider changes 2022-12-12 07:28:12 +00:00
91d7bd61be Fixed review comments and tests 2022-12-12 07:26:18 +00:00
5e7f2c1182 Fixed breaking test case 2022-12-11 16:47:35 +00:00
3d4af52c52 Renamed variables and added tests 2022-12-11 13:33:36 +00:00
d91f5bd2fd Fixed inputs 2022-12-09 13:56:33 +00:00
61aa90bfc3 Removed comments 2022-12-09 12:59:43 +00:00
0c2d18e609 Merge pull request #1024 from actions/kotewar/save-changes
Granular cache control save related changes and new inputs
2022-12-09 18:22:02 +05:30
804322aab0 Updated new actions dist files 2022-12-09 09:42:25 +00:00
f426a0deb2 Merge remote-tracking branch 'origin/700-actionscache-granular-cache-control' into kotewar/save-changes 2022-12-09 09:40:50 +00:00
be72d0432d Merge remote-tracking branch 'origin/releases/v3-beta' into 700-actionscache-granular-cache-control 2022-12-09 09:38:08 +00:00
8ecd00a4be Added restore only and save only test cases 2022-12-08 17:56:21 +00:00
12a1a354bd Fixed test cases 2022-12-08 17:39:12 +00:00
782b0bd3df Fixed test cases 2022-12-08 17:30:24 +00:00
f33ca902b8 Merge pull request #1022 from actions/phantsure/v3-beta
Release cache `3.1.0-beta.2` with gzip fallback for old cache
2022-12-08 15:39:59 +05:30
d48d03435b Add support for gzip fallback for restore of old cache on windows 2022-12-08 09:54:44 +00:00
6f77edac15 dist 2022-12-08 08:33:23 +00:00
6e12d27152 Fixed formatting 2022-12-08 08:24:43 +00:00
c346bf01e0 Merge remote-tracking branch 'origin/releases/v3-beta' into 700-actionscache-granular-cache-control 2022-12-08 07:48:07 +00:00
593e91a38b Update dist folder 2022-12-08 07:28:04 +00:00
e4c2242eff Changes for beta release 2022-12-08 07:28:03 +00:00
66ef8a0951 Merge pull request #1018 from actions/bishal/outputter
Update save with a wrapper layer
2022-12-07 17:03:07 +05:30
657c52f11e fix merge 2022-12-06 18:45:12 +00:00
34e917cb7d Merge branch '700-actionscache-granular-cache-control' into bishal/outputter 2022-12-06 18:42:19 +00:00
ac8fc97c06 update save as well 2022-12-06 18:26:58 +00:00
86712a0733 dist 2022-12-06 10:10:52 +00:00
d6e98d9302 Calling methods from same file 2022-12-06 10:08:26 +00:00
a76826ef46 Removed commented lines 2022-12-06 10:07:30 +00:00
e02e5113ed Removed return type in promise 2022-12-06 10:03:48 +00:00
85ae5bbcea Fixed breaking test case 2022-12-06 09:36:37 +00:00
cce93fb2c7 Generated dist 2022-12-06 08:23:10 +00:00
e3d8fb0b34 Merge pull request #1016 from actions/bishal/outputter
Refactor setting output and state into a generic outputter
2022-12-05 18:10:52 +05:30
020a412c27 Readme draft for new actions 2022-12-05 12:34:45 +00:00
d95c048983 refactor into a generic outputter 2022-12-05 11:36:14 +00:00
706c369cf1 Merge branch 'main' into 700-actionscache-granular-cache-control 2022-12-05 12:24:53 +05:30
11ab7ccfa2 Reverted custom asks implemented and added wrapper 2022-12-02 10:14:43 +00:00
4b5f33df54 Updated new actions' input descriptions 2022-12-01 08:27:08 +00:00
56a0133650 Merge branch 'main' into 700-actionscache-granular-cache-control 2022-11-30 16:20:50 +05:30
19446b165a Slight modification for test cases check 2022-11-30 10:47:09 +00:00
8a88690a20 Fixed test cases issues 2022-11-30 08:38:59 +00:00
6e2c6a5916 Formatted document 2022-11-30 08:30:16 +00:00
2c9fb32186 Merge branch 'main' into 700-actionscache-granular-cache-control 2022-11-30 13:57:39 +05:30
01d96636a0 Some cleanup 2022-11-30 08:26:50 +00:00
9c5a42a7c9 Added test cases 2022-11-30 08:11:55 +00:00
a172494938 Reverted wrapper changes 2022-11-29 10:56:53 +00:00
f8717682fb Impl separated 2022-11-29 09:55:41 +00:00
af1210e2a3 test 2022-11-29 09:51:53 +00:00
ab0e7714ce new try 2022-11-29 09:39:21 +00:00
fb4a5dce60 test 2022-11-29 09:33:03 +00:00
71334c58b2 Test 2022-11-29 09:06:10 +00:00
888d454557 experimenting 2022-11-29 09:03:19 +00:00
dddd7ce07c added debug logs 2022-11-29 08:26:52 +00:00
abddc4dd44 Merge remote-tracking branch 'origin/master' into 700-actionscache-granular-cache-control 2022-11-29 08:08:32 +00:00
921c58ee44 Changed logs to warnings 2022-11-29 08:06:41 +00:00
7f45813c72 Adding wrapper class 2022-11-29 08:02:27 +00:00
0769f2e443 Merge branch 'main' into master 2022-11-28 23:50:15 -08:00
5fe0b944ef Updated variable name 2022-11-29 07:48:11 +00:00
69b8227b27 Basic implementation 2022-11-25 09:16:56 +00:00
515d10b4fd Merge pull request #746 from actions/revert-173-add-stack-example
Revert "Add example for Haskell Stack"
2022-02-22 12:44:25 +05:30
669e7536d9 Revert "Add example for Haskell Stack" 2022-02-22 12:17:37 +05:30
29dbbce762 Merge pull request #173 from malob/add-stack-example
Add example for Haskell Stack
2022-02-22 12:11:06 +05:30
ea5981db97 Add example for Haskell Stack 2022-02-21 14:59:28 -08:00
16 changed files with 90 additions and 223 deletions

View File

@ -6,7 +6,7 @@
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "npm install"
"postCreateCommand": "npm install && npm run build"
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.

View File

@ -8,39 +8,45 @@ on:
jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
runs-on: ubuntu-latest
permissions:
# required for all workflows
security-events: write
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java, ruby
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below).
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following
# three lines and modify them (or add more) to build your code if your
# project uses a compiled language
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v1

View File

@ -1,6 +1,6 @@
---
name: "@actions/cache"
version: 3.1.0
version: 3.0.5
type: npm
summary:
homepage:

View File

@ -27,8 +27,6 @@ See ["Caching dependencies to speed up workflows"](https://docs.github.com/en/ac
* Fixed the download stuck problem by introducing a timeout of 1 hour for cache downloads.
* Fix zstd not working for windows on gnu tar in issues.
* Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 60 minutes.
* Two new actions available for granular control over caches - [restore](restore/action.yml) and [save](save/action.yml)
* Add support for cross os caching. For example, a cache saved on windows can be restored on ubuntu and vice versa.
Refer [here](https://github.com/actions/cache/blob/v2/README.md) for previous versions

View File

@ -52,11 +52,3 @@
### 3.2.0-beta.1
- Added two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache.
### 3.2.0
- Released the two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache
### 3.2.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))
- Added support for fallback to gzip to restore old caches on windows.
- Added logs for cache version in case of a cache miss.

View File

@ -91,31 +91,3 @@ test("save with valid inputs uploads a cache", async () => {
expect(failedMock).toHaveBeenCalledTimes(0);
});
test("save failing logs the warning message", async () => {
const warningMock = jest.spyOn(core, "warning");
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 = -1;
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(warningMock).toHaveBeenCalledTimes(1);
expect(warningMock).toHaveBeenCalledWith("Cache save failed.");
});

View File

@ -25,15 +25,16 @@ afterEach(() => {
});
test("StateProvider saves states", async () => {
const states = new Map<string, string>();
const getStateMock = jest
.spyOn(core, "getState")
.mockImplementation(key => states.get(key) || "");
.mockImplementation(name =>
jest.requireActual("@actions/core").getState(name)
);
const saveStateMock = jest
.spyOn(core, "saveState")
.mockImplementation((key, value) => {
states.set(key, value);
return jest.requireActual("@actions/core").saveState(key, value);
});
const setOutputMock = jest
@ -47,11 +48,9 @@ test("StateProvider saves states", async () => {
const stateProvider: IStateProvider = new StateProvider();
stateProvider.setState("stateKey", "stateValue");
stateProvider.setState(State.CacheMatchedKey, cacheMatchedKey);
const stateValue = stateProvider.getState("stateKey");
const cacheStateValue = stateProvider.getCacheState();
stateProvider.getState("stateKey");
stateProvider.getCacheState();
expect(stateValue).toBe("stateValue");
expect(cacheStateValue).toBe(cacheMatchedKey);
expect(getStateMock).toHaveBeenCalledTimes(2);
expect(saveStateMock).toHaveBeenCalledTimes(2);
expect(setOutputMock).toHaveBeenCalledTimes(0);

View File

@ -3431,12 +3431,8 @@ function getCacheEntry(keys, paths, options) {
const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod);
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
const response = yield requestUtils_1.retryTypedResponse('getCacheEntry', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
// Cache not found
if (response.statusCode === 204) {
// List cache for primary key only if cache miss occurs
if (core.isDebug()) {
yield printCachesListForDiagnostics(keys[0], httpClient, version);
}
// Cache not found
return null;
}
if (!requestUtils_1.isSuccessStatusCode(response.statusCode)) {
@ -3455,22 +3451,6 @@ function getCacheEntry(keys, paths, options) {
});
}
exports.getCacheEntry = getCacheEntry;
function printCachesListForDiagnostics(key, httpClient, version) {
return __awaiter(this, void 0, void 0, function* () {
const resource = `caches?key=${encodeURIComponent(key)}`;
const response = yield requestUtils_1.retryTypedResponse('listCache', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
if (response.statusCode === 200) {
const cacheListResult = response.result;
const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount;
if (totalCount && totalCount > 0) {
core.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env['GITHUB_REF']}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key \nOther caches with similar key:`);
for (const cacheEntry of (cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.artifactCaches) || []) {
core.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`);
}
}
}
});
}
function downloadCache(archiveLocation, archivePath, options) {
return __awaiter(this, void 0, void 0, function* () {
const archiveUrl = new url_1.URL(archiveLocation);
@ -38349,7 +38329,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -d --long=30 --force -o',
'zstd -d --long=30 -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38360,7 +38340,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -d --force -o',
'zstd -d -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38386,7 +38366,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -T0 --long=30 --force -o',
'zstd -T0 --long=30 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -38397,7 +38377,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -T0 --force -o',
'zstd -T0 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -47276,7 +47256,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
return undefined;
}
core.info("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
core.debug("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
}
else {
// Cache not found

32
dist/restore/index.js vendored
View File

@ -3431,12 +3431,8 @@ function getCacheEntry(keys, paths, options) {
const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod);
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
const response = yield requestUtils_1.retryTypedResponse('getCacheEntry', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
// Cache not found
if (response.statusCode === 204) {
// List cache for primary key only if cache miss occurs
if (core.isDebug()) {
yield printCachesListForDiagnostics(keys[0], httpClient, version);
}
// Cache not found
return null;
}
if (!requestUtils_1.isSuccessStatusCode(response.statusCode)) {
@ -3455,22 +3451,6 @@ function getCacheEntry(keys, paths, options) {
});
}
exports.getCacheEntry = getCacheEntry;
function printCachesListForDiagnostics(key, httpClient, version) {
return __awaiter(this, void 0, void 0, function* () {
const resource = `caches?key=${encodeURIComponent(key)}`;
const response = yield requestUtils_1.retryTypedResponse('listCache', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
if (response.statusCode === 200) {
const cacheListResult = response.result;
const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount;
if (totalCount && totalCount > 0) {
core.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env['GITHUB_REF']}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key \nOther caches with similar key:`);
for (const cacheEntry of (cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.artifactCaches) || []) {
core.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`);
}
}
}
});
}
function downloadCache(archiveLocation, archivePath, options) {
return __awaiter(this, void 0, void 0, function* () {
const archiveUrl = new url_1.URL(archiveLocation);
@ -38262,7 +38242,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -d --long=30 --force -o',
'zstd -d --long=30 -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38273,7 +38253,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -d --force -o',
'zstd -d -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38299,7 +38279,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -T0 --long=30 --force -o',
'zstd -T0 --long=30 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -38310,7 +38290,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -T0 --force -o',
'zstd -T0 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -47247,7 +47227,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
return undefined;
}
core.info("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
core.debug("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
}
else {
// Cache not found

View File

@ -1043,29 +1043,6 @@ class ExecState extends events.EventEmitter {
"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) {
@ -1079,15 +1056,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(__webpack_require__(470));
const saveImpl_1 = __importDefault(__webpack_require__(471));
const stateProvider_1 = __webpack_require__(309);
function run() {
return __awaiter(this, void 0, void 0, function* () {
const cacheId = yield (0, saveImpl_1.default)(new stateProvider_1.NullStateProvider());
if (cacheId === -1) {
core.warning(`Cache save failed.`);
}
yield (0, saveImpl_1.default)(new stateProvider_1.NullStateProvider());
});
}
run();
@ -3487,12 +3460,8 @@ function getCacheEntry(keys, paths, options) {
const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod);
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
const response = yield requestUtils_1.retryTypedResponse('getCacheEntry', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
// Cache not found
if (response.statusCode === 204) {
// List cache for primary key only if cache miss occurs
if (core.isDebug()) {
yield printCachesListForDiagnostics(keys[0], httpClient, version);
}
// Cache not found
return null;
}
if (!requestUtils_1.isSuccessStatusCode(response.statusCode)) {
@ -3511,22 +3480,6 @@ function getCacheEntry(keys, paths, options) {
});
}
exports.getCacheEntry = getCacheEntry;
function printCachesListForDiagnostics(key, httpClient, version) {
return __awaiter(this, void 0, void 0, function* () {
const resource = `caches?key=${encodeURIComponent(key)}`;
const response = yield requestUtils_1.retryTypedResponse('listCache', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
if (response.statusCode === 200) {
const cacheListResult = response.result;
const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount;
if (totalCount && totalCount > 0) {
core.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env['GITHUB_REF']}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key \nOther caches with similar key:`);
for (const cacheEntry of (cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.artifactCaches) || []) {
core.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`);
}
}
}
});
}
function downloadCache(archiveLocation, archivePath, options) {
return __awaiter(this, void 0, void 0, function* () {
const archiveUrl = new url_1.URL(archiveLocation);
@ -38313,7 +38266,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -d --long=30 --force -o',
'zstd -d --long=30 -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38324,7 +38277,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -d --force -o',
'zstd -d -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38350,7 +38303,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -T0 --long=30 --force -o',
'zstd -T0 --long=30 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -38361,7 +38314,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -T0 --force -o',
'zstd -T0 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -41139,7 +41092,6 @@ const utils = __importStar(__webpack_require__(443));
process.on("uncaughtException", e => utils.logWarning(e.message));
function saveImpl(stateProvider) {
return __awaiter(this, void 0, void 0, function* () {
let cacheId = -1;
try {
if (!utils.isCacheFeatureAvailable()) {
return;
@ -41166,7 +41118,7 @@ function saveImpl(stateProvider) {
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
required: true
});
cacheId = yield cache.saveCache(cachePaths, primaryKey, {
const cacheId = yield cache.saveCache(cachePaths, primaryKey, {
uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize)
});
if (cacheId != -1) {
@ -41176,7 +41128,6 @@ function saveImpl(stateProvider) {
catch (error) {
utils.logWarning(error.message);
}
return cacheId;
});
}
exports.default = saveImpl;
@ -47389,7 +47340,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
return undefined;
}
core.info("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
core.debug("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
}
else {
// Cache not found

36
dist/save/index.js vendored
View File

@ -3431,12 +3431,8 @@ function getCacheEntry(keys, paths, options) {
const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod);
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
const response = yield requestUtils_1.retryTypedResponse('getCacheEntry', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
// Cache not found
if (response.statusCode === 204) {
// List cache for primary key only if cache miss occurs
if (core.isDebug()) {
yield printCachesListForDiagnostics(keys[0], httpClient, version);
}
// Cache not found
return null;
}
if (!requestUtils_1.isSuccessStatusCode(response.statusCode)) {
@ -3455,22 +3451,6 @@ function getCacheEntry(keys, paths, options) {
});
}
exports.getCacheEntry = getCacheEntry;
function printCachesListForDiagnostics(key, httpClient, version) {
return __awaiter(this, void 0, void 0, function* () {
const resource = `caches?key=${encodeURIComponent(key)}`;
const response = yield requestUtils_1.retryTypedResponse('listCache', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
if (response.statusCode === 200) {
const cacheListResult = response.result;
const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount;
if (totalCount && totalCount > 0) {
core.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env['GITHUB_REF']}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key \nOther caches with similar key:`);
for (const cacheEntry of (cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.artifactCaches) || []) {
core.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`);
}
}
}
});
}
function downloadCache(archiveLocation, archivePath, options) {
return __awaiter(this, void 0, void 0, function* () {
const archiveUrl = new url_1.URL(archiveLocation);
@ -38257,7 +38237,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -d --long=30 --force -o',
'zstd -d --long=30 -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38268,7 +38248,7 @@ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -d --force -o',
'zstd -d -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
@ -38294,7 +38274,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -T0 --long=30 --force -o',
'zstd -T0 --long=30 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -38305,7 +38285,7 @@ function getCompressionProgram(tarPath, compressionMethod) {
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -T0 --force -o',
'zstd -T0 -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
@ -41083,7 +41063,6 @@ const utils = __importStar(__webpack_require__(443));
process.on("uncaughtException", e => utils.logWarning(e.message));
function saveImpl(stateProvider) {
return __awaiter(this, void 0, void 0, function* () {
let cacheId = -1;
try {
if (!utils.isCacheFeatureAvailable()) {
return;
@ -41110,7 +41089,7 @@ function saveImpl(stateProvider) {
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
required: true
});
cacheId = yield cache.saveCache(cachePaths, primaryKey, {
const cacheId = yield cache.saveCache(cachePaths, primaryKey, {
uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize)
});
if (cacheId != -1) {
@ -41120,7 +41099,6 @@ function saveImpl(stateProvider) {
catch (error) {
utils.logWarning(error.message);
}
return cacheId;
});
}
exports.default = saveImpl;
@ -47362,7 +47340,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
return undefined;
}
core.info("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
core.debug("Couldn't find cache entry with zstd compression, falling back to gzip compression.");
}
else {
// Cache not found

18
package-lock.json generated
View File

@ -1,15 +1,15 @@
{
"name": "cache",
"version": "3.2.1",
"version": "3.2.0-beta.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cache",
"version": "3.2.1",
"version": "3.2.0-beta.1",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.1.0",
"@actions/cache": "3.1.0-beta.3",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.2"
@ -36,9 +36,9 @@
}
},
"node_modules/@actions/cache": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.1.0.tgz",
"integrity": "sha512-wKGJkpK3uFTgwy+KA0fxz0H3/ZPymdi0IlyhMmyoMeWd+CIv8xVPWdGlrPDDdN9bFgve2yvEPZVaKRb43Uwtyg==",
"version": "3.1.0-beta.3",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.1.0-beta.3.tgz",
"integrity": "sha512-71S1vd0WKLbC2lAe04pCYqTLBjSa8gURtiqnVBCYAt8QVBjOfwa2D3ESf2m8K2xjUxman/Yimdp7CPJDyFnxZg==",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.0.1",
@ -9722,9 +9722,9 @@
},
"dependencies": {
"@actions/cache": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.1.0.tgz",
"integrity": "sha512-wKGJkpK3uFTgwy+KA0fxz0H3/ZPymdi0IlyhMmyoMeWd+CIv8xVPWdGlrPDDdN9bFgve2yvEPZVaKRb43Uwtyg==",
"version": "3.1.0-beta.3",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.1.0-beta.3.tgz",
"integrity": "sha512-71S1vd0WKLbC2lAe04pCYqTLBjSa8gURtiqnVBCYAt8QVBjOfwa2D3ESf2m8K2xjUxman/Yimdp7CPJDyFnxZg==",
"requires": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "cache",
"version": "3.2.1",
"version": "3.2.0-beta.1",
"private": true,
"description": "Cache dependencies and build outputs",
"main": "dist/restore/index.js",
@ -23,7 +23,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.1.0",
"@actions/cache": "3.1.0-beta.3",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.2"

View File

@ -10,8 +10,7 @@ import * as utils from "./utils/actionUtils";
// 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<number | void> {
let cacheId = -1;
async function saveImpl(stateProvider: IStateProvider): Promise<void> {
try {
if (!utils.isCacheFeatureAvailable()) {
return;
@ -52,7 +51,7 @@ async function saveImpl(stateProvider: IStateProvider): Promise<number | void> {
required: true
});
cacheId = await cache.saveCache(cachePaths, primaryKey, {
const cacheId = await cache.saveCache(cachePaths, primaryKey, {
uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize)
});
@ -62,7 +61,6 @@ async function saveImpl(stateProvider: IStateProvider): Promise<number | void> {
} catch (error: unknown) {
utils.logWarning((error as Error).message);
}
return cacheId;
}
export default saveImpl;

View File

@ -1,13 +1,8 @@
import * as core from "@actions/core";
import saveImpl from "./saveImpl";
import { NullStateProvider } from "./stateProvider";
async function run(): Promise<void> {
const cacheId = await saveImpl(new NullStateProvider());
if (cacheId === -1) {
core.warning(`Cache save failed.`);
}
await saveImpl(new NullStateProvider());
}
run();

View File

@ -19,6 +19,24 @@ A cache today is immutable and cannot be updated. But some use cases require the
## Use cache across feature branches
Reusing cache across feature branches is not allowed today to provide cache [isolation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache). However if both feature branches are from the default branch, a good way to achieve this is to ensure that the default branch has a cache. This cache will then be consumable by both feature branches.
## Improving cache restore performance on Windows/Using cross-os caching
Currently, cache restore is slow on Windows due to tar being inherently slow and the compression algorithm `gzip` in use. `zstd` is the default algorithm in use on linux and macos. It was disabled on Windows due to issues with bsd tar(libarchive), the tar implementation in use on Windows.
To improve cache restore performance, we can re-enable `zstd` as the compression algorithm using the following workaround. Add the following step to your workflow before the cache step:
```yaml
- if: ${{ runner.os == 'Windows' }}
name: Use GNU tar
shell: cmd
run: |
echo "Adding GNU tar to PATH"
echo C:\Program Files\Git\usr\bin>>"%GITHUB_PATH%"
```
The `cache` action will use GNU tar instead of bsd tar on Windows. This should work on all Github Hosted runners as it is. For self-hosted runners, please ensure you have GNU tar and `zstd` installed.
The above workaround is also needed if you wish to use cross-os caching since difference of compression algorithms will result in different cache versions for the same cache key. So the above workaround will ensure `zstd` is used for caching on all platforms thus resulting in the same cache version for the same cache key.
## Force deletion of caches overriding default cache eviction policy
Caches have [branch scope restriction](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache) in place. This means that if caches for a specific branch are using a lot of storage quota, it may result into more frequently used caches from `default` branch getting thrashed. For example, if there are many pull requests happening on a repo and are creating caches, these cannot be used in default branch scope but will still occupy a lot of space till they get cleaned up by [eviction policy](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy). But sometime we want to clean them up on a faster cadence so as to ensure default branch is not thrashing. In order to achieve this, [gh-actions-cache cli](https://github.com/actions/gh-actions-cache/) can be used to delete caches for specific branches.