Compare commits

...

12 Commits

Author SHA1 Message Date
af22881f86 new release 2022-07-12 18:32:42 +00:00
354a2ae15e Consuming 3.0 actions/cache (#834)
* Consuming 3.0 actions/cache

* formatting and error

* updated package version

* resolve package

* dist

* review comment

* dist

* dist
2022-07-07 21:56:17 +05:30
baed3516c3 Merge pull request #530 from axelson/document-where-to-cache
Make it more obvious that the cache call does double duty
2022-06-27 10:56:37 +05:30
8829e97be1 Update README.md
Co-authored-by: Lucas Costi <lucascosti@users.noreply.github.com>
2022-06-27 10:48:52 +05:30
eec8cd3f5f Merge pull request #836 from actions/vsvipul/fix-auto-assign
Add kotewar and remove phantsure from auto-assignees lists
2022-06-26 20:03:54 +05:30
5cc84c0123 Add kotewar and remove phantsure from auto-assignees lists 2022-06-26 05:26:49 +00:00
afc669e7fc Merge pull request #819 from mpilgrem/haskell-stack-example
Adapt existing Haskell Stack example for Windows
2022-06-23 16:13:06 +05:30
a0efc56c52 Use pull_request_target instead of pull_request
Fixes autoassign reviewer for PRs from forked repos.
2022-06-21 22:38:08 +05:30
d25c51bbfd Adapt existing Haskell Stack example for Windows
The default `STACK_ROOT` is `~/.stack` only on Unix-like operating systems. On Windows, the default is `%APPDATA%/stack` (usually `%HOME%\AppData\Roaming\stack`).

On Unix-like OSs, Stack stores GHC and other tools in a `programs` directory in the `STACK_ROOT`. On Windows, Stack stores those tools and MSYS2 in `%LOCALAPPDATA%\Programs\stack` (usually `%HOME%\AppData\Local\Programs\stack`).
2022-06-21 13:15:08 +01:00
a080a3bda4 Merge pull request #816 from lobis/main
Fixed bad yaml in README example
2022-06-21 09:55:20 +05:30
02be3a9c73 fixed bad yaml in README example 2022-06-08 21:43:57 +02:00
2086306d9c Make it more obvious that the cache call does double duty 2021-02-06 13:36:42 -10:00
15 changed files with 183 additions and 183 deletions

View File

@ -6,7 +6,7 @@ addAssignees: false
# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
- phantsure
- kotewar
- aparna-ravindra
- tiwarishub
- vsvipul

View File

@ -11,5 +11,5 @@ jobs:
- name: 'Auto-assign issue'
uses: pozil/auto-assign-issue@v1.4.0
with:
assignees: phantsure,tiwarishub,aparna-ravindra,vsvipul,bishal-pdmsft
assignees: kotewar,tiwarishub,aparna-ravindra,vsvipul,bishal-pdmsft
numOfAssignee: 1

View File

@ -1,6 +1,6 @@
name: 'Auto Assign'
on:
pull_request:
pull_request_target:
types: [opened, ready_for_review]
jobs:

View File

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

View File

@ -72,6 +72,8 @@ jobs:
run: /primes.sh -d prime-numbers
```
> Note: You must use the `cache` action in your workflow before you need to use the files that might be restored from the cache. If the provided `key` doesn't match an existing cache, a new cache is automatically created if the job completes successfully.
## Implementation Examples
Every programming language and framework has its own way of caching.
@ -172,33 +174,33 @@ jobs:
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v3
- name: Cache Primes
id: cache-primes
uses: actions/cache@v3
with:
path: prime-numbers
key: primes
- name: Cache Primes
id: cache-primes
uses: actions/cache@v3
with:
path: prime-numbers
key: primes
- name: Generate Prime Numbers
if: steps.cache-primes.outputs.cache-hit != 'true'
run: ./generate-primes.sh -d prime-numbers
- name: Cache Numbers
id: cache-numbers
uses: actions/cache@v3
with:
path: numbers
key: primes
- name: Generate Prime Numbers
if: steps.cache-primes.outputs.cache-hit != 'true'
run: ./generate-primes.sh -d prime-numbers
- name: Generate Numbers
if: steps.cache-numbers.outputs.cache-hit != 'true'
run: ./generate-primes.sh -d numbers
build-windows:
runs-on: windows-latest
steps:
- name: Cache Numbers
id: cache-numbers
uses: actions/cache@v3
with:
path: numbers
key: primes
- name: Generate Numbers
if: steps.cache-numbers.outputs.cache-hit != 'true'
run: ./generate-primes.sh -d numbers
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Cache Primes

View File

@ -14,4 +14,7 @@
- Fixed avoiding empty cache save when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
### 3.0.4
- Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. ([issue](https://github.com/actions/cache/issues/689))
- Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. ([issue](https://github.com/actions/cache/issues/689))
### 3.0.5
- Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. ([PR](https://github.com/actions/cache/pull/834))

View File

@ -227,40 +227,6 @@ test("restore with no cache found", async () => {
);
});
test("restore with server error should fail", async () => {
const path = "node_modules";
const key = "node-test";
testUtils.setInputs({
path: path,
key
});
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
const failedMock = jest.spyOn(core, "setFailed");
const stateMock = jest.spyOn(core, "saveState");
const restoreCacheMock = jest
.spyOn(cache, "restoreCache")
.mockImplementationOnce(() => {
throw new Error("HTTP Error Occurred");
});
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(logWarningMock).toHaveBeenCalledTimes(1);
expect(logWarningMock).toHaveBeenCalledWith("HTTP Error Occurred");
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
expect(failedMock).toHaveBeenCalledTimes(0);
});
test("restore with restore keys and no cache found", async () => {
const path = "node_modules";
const key = "node-test";

View File

@ -267,7 +267,6 @@ test("save with large cache outputs warning", async () => {
});
test("save with reserve cache failure outputs warning", async () => {
const infoMock = jest.spyOn(core, "info");
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
const failedMock = jest.spyOn(core, "setFailed");
@ -306,10 +305,10 @@ test("save with reserve cache failure outputs warning", async () => {
expect.anything()
);
expect(infoMock).toHaveBeenCalledWith(
expect(logWarningMock).toHaveBeenCalledWith(
`Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.`
);
expect(logWarningMock).toHaveBeenCalledTimes(0);
expect(logWarningMock).toHaveBeenCalledTimes(1);
expect(failedMock).toHaveBeenCalledTimes(0);
});

84
dist/restore/index.js vendored
View File

@ -46850,17 +46850,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
checkKey(key);
}
const compressionMethod = yield utils.getCompressionMethod();
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
let archivePath = '';
try {
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
// Download the cache from the cache entry
yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options);
if (core.isDebug()) {
@ -46870,6 +46871,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
yield tar_1.extractTar(archivePath, compressionMethod);
core.info('Cache restored successfully');
return cacheEntry.cacheKey;
}
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else {
// Supress all non-validation cache related errors because caching should be optional
core.warning(`Failed to restore: ${error.message}`);
}
}
finally {
// Try to delete the archive to save space
@ -46880,7 +46892,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.debug(`Failed to delete archive: ${error}`);
}
}
return cacheEntry.cacheKey;
return undefined;
});
}
exports.restoreCache = restoreCache;
@ -46898,7 +46910,7 @@ function saveCache(paths, key, options) {
checkPaths(paths);
checkKey(key);
const compressionMethod = yield utils.getCompressionMethod();
let cacheId = null;
let cacheId = -1;
const cachePaths = yield utils.resolvePaths(paths);
core.debug('Cache Paths:');
core.debug(`${JSON.stringify(cachePaths)}`);
@ -46937,6 +46949,18 @@ function saveCache(paths, key, options) {
core.debug(`Saving Cache (ID: ${cacheId})`);
yield cacheHttpClient.saveCache(cacheId, archivePath, options);
}
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else if (typedError.name === ReserveCacheError.name) {
core.info(`Failed to save: ${typedError.message}`);
}
else {
core.warning(`Failed to save: ${typedError.message}`);
}
}
finally {
// Try to delete the archive to save space
try {
@ -48996,31 +49020,19 @@ function run() {
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
required: true
});
try {
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
utils.setCacheState(cacheKey);
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
utils.setCacheHitOutput(isExactKeyMatch);
core.info(`Cache restored from key: ${cacheKey}`);
}
catch (error) {
const typedError = error;
if (typedError.name === cache.ValidationError.name) {
throw error;
}
else {
utils.logWarning(typedError.message);
utils.setCacheHitOutput(false);
}
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
utils.setCacheState(cacheKey);
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
utils.setCacheHitOutput(isExactKeyMatch);
core.info(`Cache restored from key: ${cacheKey}`);
}
catch (error) {
core.setFailed(error.message);

68
dist/save/index.js vendored
View File

@ -46792,24 +46792,12 @@ function run() {
const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
required: true
});
try {
yield cache.saveCache(cachePaths, primaryKey, {
uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize)
});
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) {
const typedError = error;
if (typedError.name === cache.ValidationError.name) {
throw error;
}
else if (typedError.name === cache.ReserveCacheError.name) {
core.info(typedError.message);
}
else {
utils.logWarning(typedError.message);
}
}
}
catch (error) {
utils.logWarning(error.message);
@ -46948,17 +46936,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
checkKey(key);
}
const compressionMethod = yield utils.getCompressionMethod();
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
let archivePath = '';
try {
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
// Download the cache from the cache entry
yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options);
if (core.isDebug()) {
@ -46968,6 +46957,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
yield tar_1.extractTar(archivePath, compressionMethod);
core.info('Cache restored successfully');
return cacheEntry.cacheKey;
}
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else {
// Supress all non-validation cache related errors because caching should be optional
core.warning(`Failed to restore: ${error.message}`);
}
}
finally {
// Try to delete the archive to save space
@ -46978,7 +46978,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.debug(`Failed to delete archive: ${error}`);
}
}
return cacheEntry.cacheKey;
return undefined;
});
}
exports.restoreCache = restoreCache;
@ -46996,7 +46996,7 @@ function saveCache(paths, key, options) {
checkPaths(paths);
checkKey(key);
const compressionMethod = yield utils.getCompressionMethod();
let cacheId = null;
let cacheId = -1;
const cachePaths = yield utils.resolvePaths(paths);
core.debug('Cache Paths:');
core.debug(`${JSON.stringify(cachePaths)}`);
@ -47035,6 +47035,18 @@ function saveCache(paths, key, options) {
core.debug(`Saving Cache (ID: ${cacheId})`);
yield cacheHttpClient.saveCache(cacheId, archivePath, options);
}
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else if (typedError.name === ReserveCacheError.name) {
core.info(`Failed to save: ${typedError.message}`);
}
else {
core.warning(`Failed to save: ${typedError.message}`);
}
}
finally {
// Try to delete the archive to save space
try {

View File

@ -223,6 +223,8 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
## Haskell - Stack
### Linux or macOS
```yaml
- uses: actions/cache@v3
name: Cache ~/.stack
@ -240,6 +242,27 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
${{ runner.os }}-stack-work-
```
### Windows
```yaml
- uses: actions/cache@v3
name: Cache %APPDATA%\stack %LOCALAPPDATA%\Programs\stack
with:
path: |
~\AppData\Roaming\stack
~\AppData\Local\Programs\stack
key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
restore-keys: |
${{ runner.os }}-stack-global-
- uses: actions/cache@v3
name: Cache .stack-work
with:
path: .stack-work
key: ${{ runner.os }}-stack-work-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}-${{ hashFiles('**/*.hs') }}
restore-keys: |
${{ runner.os }}-stack-work-
```
## Java - Gradle
>Note: Ensure no Gradle daemons are running anymore when your workflow completes. Creating the cache package might fail due to locks being held by Gradle. Refer to the [Gradle Daemon documentation](https://docs.gradle.org/current/userguide/gradle_daemon.html) on how to disable or stop the Gradle Daemons.

18
package-lock.json generated
View File

@ -1,15 +1,15 @@
{
"name": "cache",
"version": "3.0.4",
"version": "3.0.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cache",
"version": "3.0.4",
"version": "3.0.5",
"license": "MIT",
"dependencies": {
"@actions/cache": "^2.0.6",
"@actions/cache": "^3.0.0",
"@actions/core": "^1.7.0",
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.2"
@ -36,9 +36,9 @@
}
},
"node_modules/@actions/cache": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.6.tgz",
"integrity": "sha512-Z39ZrWaTRRPaV/AOQdY7hve+Iy/HloH5prpz+k+0lZgGQs/3SeO0UYSIakVuXOk2pdMZnl0Nv0PoK1rmh9YfGQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.0.tgz",
"integrity": "sha512-GL9CT1Fnu+pqs8TTB621q8Xa8Cilw2n9MwvbgMedetH7L1q2n6jY61gzbwGbKgtVbp3gVJ12aNMi4osSGXx3KQ==",
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1",
@ -9533,9 +9533,9 @@
},
"dependencies": {
"@actions/cache": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.6.tgz",
"integrity": "sha512-Z39ZrWaTRRPaV/AOQdY7hve+Iy/HloH5prpz+k+0lZgGQs/3SeO0UYSIakVuXOk2pdMZnl0Nv0PoK1rmh9YfGQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.0.tgz",
"integrity": "sha512-GL9CT1Fnu+pqs8TTB621q8Xa8Cilw2n9MwvbgMedetH7L1q2n6jY61gzbwGbKgtVbp3gVJ12aNMi4osSGXx3KQ==",
"requires": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "cache",
"version": "3.0.4",
"version": "3.0.5",
"private": true,
"description": "Cache dependencies and build outputs",
"main": "dist/restore/index.js",
@ -23,7 +23,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^2.0.6",
"@actions/cache": "^3.0.0",
"@actions/core": "^1.7.0",
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.2"

View File

@ -29,38 +29,29 @@ async function run(): Promise<void> {
required: true
});
try {
const cacheKey = await cache.restoreCache(
cachePaths,
primaryKey,
restoreKeys
const cacheKey = await cache.restoreCache(
cachePaths,
primaryKey,
restoreKeys
);
if (!cacheKey) {
core.info(
`Cache not found for input keys: ${[
primaryKey,
...restoreKeys
].join(", ")}`
);
if (!cacheKey) {
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);
core.info(`Cache restored from key: ${cacheKey}`);
} catch (error: unknown) {
const typedError = error as Error;
if (typedError.name === cache.ValidationError.name) {
throw error;
} else {
utils.logWarning(typedError.message);
utils.setCacheHitOutput(false);
}
return;
}
// Store the matched cache key
utils.setCacheState(cacheKey);
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
utils.setCacheHitOutput(isExactKeyMatch);
core.info(`Cache restored from key: ${cacheKey}`);
} catch (error: unknown) {
core.setFailed((error as Error).message);
}

View File

@ -44,20 +44,12 @@ async function run(): Promise<void> {
required: true
});
try {
await cache.saveCache(cachePaths, primaryKey, {
uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize)
});
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) {
const typedError = error as Error;
if (typedError.name === cache.ValidationError.name) {
throw error;
} else if (typedError.name === cache.ReserveCacheError.name) {
core.info(typedError.message);
} else {
utils.logWarning(typedError.message);
}
}
} catch (error: unknown) {
utils.logWarning((error as Error).message);