Skip to content

Commit 8f1998e

Browse files
authored
feat: add custom cache key and cache restore key input (#47)
* refactor: add github job id in cache primary key * feat: add cache-restore-key action input * refactor: allow list of restore keys * docs: update README * fix: append prefix on restore keys * refactor: rename variable for better readability * refactor: abstract primary and restore key gets * chore: run build for dist * chore: reduce verbose comments * refactor: default to prefix + github.sha on bad input
1 parent 362aa1b commit 8f1998e

File tree

8 files changed

+365
-27
lines changed

8 files changed

+365
-27
lines changed

README.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ jobs:
3131
3232
### Inputs
3333
34-
| **Name** | **Required** | **Default** | **Description** | **Type** |
35-
| --------- | ------------ | ----------- | ------------------------------------------------------------------------------------------------------------ | -------- |
36-
| `cache` | No | `true` | Whether to cache RPC responses or not. | bool |
37-
| `version` | No | `nightly` | Version to install, e.g. `nightly` or `1.0.0`. **Note:** Foundry only has nightly builds for the time being. | string |
34+
| **Name** | **Required** | **Default** | **Description** | **Type** |
35+
| -------------------- | ------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -------- |
36+
| `cache` | No | `true` | Whether to cache RPC responses or not. | bool |
37+
| `version` | No | `nightly` | Version to install, e.g. `nightly` or `1.0.0`. **Note:** Foundry only has nightly builds for the time being. | string |
38+
| `cache-key` | No | `${{ github.job }}-${{ github.sha }}` | The cache key to use for caching. | string |
39+
| `cache-restore-keys` | No | `[${{ github.job }}-]` | The cache keys to use for restoring the cache. | string[] |
3840

3941
### RPC Caching
4042

@@ -58,6 +60,34 @@ the `cache` input to `false`, like this:
5860
cache: false
5961
```
6062

63+
### Custom Cache Keys
64+
65+
You have the ability to define custom cache keys by utilizing the `cache-key` and `cache-restore-keys` inputs. This
66+
feature is particularly beneficial when you aim to tailor the cache-sharing strategy across multiple jobs. It is
67+
important to ensure that the `cache-key` is unique for each execution to prevent conflicts and guarantee successful
68+
cache saving.
69+
70+
For instance, if you wish to utilize a shared cache between two distinct jobs, the following configuration can be
71+
applied:
72+
73+
```yml
74+
- name: Install Foundry
75+
uses: foundry-rs/foundry-toolchain@v1
76+
with:
77+
cache-key: custom-seed-test-${{ github.sha }}
78+
cache-restore-keys: |-
79+
custom-seed-test-
80+
custom-seed-
81+
---
82+
- name: Install Foundry
83+
uses: foundry-rs/foundry-toolchain@v1
84+
with:
85+
cache-key: custom-seed-coverage-${{ github.sha }}
86+
cache-restore-keys: |-
87+
custom-seed-coverage-
88+
custom-seed-
89+
```
90+
6191
#### Deleting Caches
6292

6393
You can delete caches via the GitHub Actions user interface. Just go to your repo's "Actions" page:

action.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@ inputs:
1313
1414
Caching is activated by default.
1515
required: false
16+
cache-key:
17+
default: "${{ github.job }}-${{ github.sha }}"
18+
description: |
19+
A custom cache key to use.
20+
21+
This key is used to identify the cache. If not provided, a default key consisting of the job id and the commit hash is used.
22+
required: false
23+
cache-restore-keys:
24+
default: |-
25+
${{ github.job }}-
26+
description: |
27+
Custom cache restore keys to use.
28+
29+
This key is used to identify the cache to restore. If not provided, a default key consisting of the job id is used.
30+
required: false
1631
version:
1732
default: "nightly"
1833
description: |

dist/index.js

Lines changed: 118 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86178,32 +86178,98 @@ const github = __nccwpck_require__(5438);
8617886178
const fs = __nccwpck_require__(7147);
8617986179
const os = __nccwpck_require__(2037);
8618086180
const path = __nccwpck_require__(1017);
86181+
const { State } = __nccwpck_require__(4438);
8618186182

86183+
// Define constants for cache paths and prefix
8618286184
const HOME = os.homedir();
8618386185
const PLATFORM = os.platform();
8618486186
const CACHE_PATHS = [path.join(HOME, ".foundry/cache/rpc")];
86187+
const CACHE_PREFIX = `${PLATFORM}-foundry-chain-fork-`;
8618586188

86189+
/**
86190+
* Constructs the primary key for the cache using a custom key input.
86191+
* @param {string} customKeyInput - The custom part of the key provided by the user.
86192+
* @returns {string} The complete primary key for the cache.
86193+
*/
86194+
function getPrimaryKey(customKeyInput) {
86195+
if (!customKeyInput) {
86196+
return `${CACHE_PREFIX}${github.context.sha}`;
86197+
}
86198+
return `${CACHE_PREFIX}${customKeyInput.trim()}`;
86199+
}
86200+
86201+
/**
86202+
* Constructs an array of restore keys based on user input and a default prefix.
86203+
* @param {string} customRestoreKeysInput - Newline-separated string of custom restore keys.
86204+
* @returns {string[]} An array of restore keys for the cache.
86205+
*/
86206+
function getRestoreKeys(customRestoreKeysInput) {
86207+
const defaultRestoreKeys = [CACHE_PREFIX];
86208+
if (!customRestoreKeysInput) {
86209+
return defaultRestoreKeys;
86210+
}
86211+
const restoreKeys = customRestoreKeysInput
86212+
.split(/[\r\n]/)
86213+
.map((input) => input.trim())
86214+
.filter((input) => input !== "")
86215+
.map((input) => `${CACHE_PREFIX}${input}`);
86216+
return [...restoreKeys, ...defaultRestoreKeys];
86217+
}
86218+
86219+
/**
86220+
* Restores the RPC cache using the provided keys.
86221+
*/
8618686222
async function restoreRPCCache() {
86187-
const primaryKey = PLATFORM + "-foundry-chain-fork-" + github.context.sha;
86188-
const restoreKeys = [PLATFORM + "-foundry-chain-fork-"];
86189-
const cacheKey = await cache.restoreCache(CACHE_PATHS, primaryKey, restoreKeys);
86190-
if (!cacheKey) {
86223+
const customKeyInput = core.getInput("cache-key");
86224+
const primaryKey = getPrimaryKey(customKeyInput);
86225+
core.saveState(State.CachePrimaryKey, primaryKey);
86226+
86227+
const customRestoreKeysInput = core.getInput("cache-restore-keys");
86228+
const restoreKeys = getRestoreKeys(customRestoreKeysInput);
86229+
const matchedKey = await cache.restoreCache(CACHE_PATHS, primaryKey, restoreKeys);
86230+
86231+
if (!matchedKey) {
8619186232
core.info("Cache not found");
8619286233
return;
8619386234
}
86194-
core.info(`Cache restored from key: ${cacheKey}`);
86235+
86236+
core.saveState(State.CacheMatchedKey, matchedKey);
86237+
core.info(`Cache restored from key: ${matchedKey}`);
8619586238
}
8619686239

86240+
/**
86241+
* Saves the RPC cache using the primary key saved in the state.
86242+
* If the cache was already saved with the primary key, it will not save it again.
86243+
*/
8619786244
async function saveCache() {
86198-
const primaryKey = PLATFORM + "-foundry-chain-fork-" + github.context.sha;
86245+
const primaryKey = core.getState(State.CachePrimaryKey);
86246+
const matchedKey = core.getState(State.CacheMatchedKey);
86247+
86248+
// If the cache path does not exist, do not save the cache
8619986249
if (!fs.existsSync(CACHE_PATHS[0])) {
86200-
core.info(`Cache path does not exist, not saving cache : ${CACHE_PATHS[0]}`);
86250+
core.info(`Cache path does not exist, not saving cache: ${CACHE_PATHS[0]}`);
8620186251
return;
8620286252
}
86253+
86254+
// If the primary key is not generated, do not save the cache
86255+
if (!primaryKey) {
86256+
core.info("Primary key was not generated. Please check the log messages above for more errors or information");
86257+
return;
86258+
}
86259+
86260+
// If the primary key and the matched key are the same, this means the cache was already saved
86261+
if (primaryKey === matchedKey) {
86262+
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
86263+
return;
86264+
}
86265+
8620386266
const cacheId = await cache.saveCache(CACHE_PATHS, primaryKey);
86267+
86268+
// If the cacheId is -1, the saving failed with an error message log. No additional logging is needed.
8620486269
if (cacheId === -1) {
8620586270
return;
8620686271
}
86272+
8620786273
core.info(`Cache saved with the key: ${primaryKey}`);
8620886274
}
8620986275

@@ -86213,6 +86279,23 @@ module.exports = {
8621386279
};
8621486280

8621586281

86282+
/***/ }),
86283+
86284+
/***/ 4438:
86285+
/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
86286+
86287+
"use strict";
86288+
__nccwpck_require__.r(__webpack_exports__);
86289+
/* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
86290+
/* harmony export */ "State": () => (/* binding */ State)
86291+
/* harmony export */ });
86292+
// Enum for the cache primary key and result key.
86293+
const State = {
86294+
CachePrimaryKey: "CACHE_KEY",
86295+
CacheMatchedKey: "CACHE_RESULT",
86296+
};
86297+
86298+
8621686299
/***/ }),
8621786300

8621886301
/***/ 4351:
@@ -86610,6 +86693,34 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"]
8661086693
/******/ }
8661186694
/******/
8661286695
/************************************************************************/
86696+
/******/ /* webpack/runtime/define property getters */
86697+
/******/ (() => {
86698+
/******/ // define getter functions for harmony exports
86699+
/******/ __nccwpck_require__.d = (exports, definition) => {
86700+
/******/ for(var key in definition) {
86701+
/******/ if(__nccwpck_require__.o(definition, key) && !__nccwpck_require__.o(exports, key)) {
86702+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
86703+
/******/ }
86704+
/******/ }
86705+
/******/ };
86706+
/******/ })();
86707+
/******/
86708+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
86709+
/******/ (() => {
86710+
/******/ __nccwpck_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
86711+
/******/ })();
86712+
/******/
86713+
/******/ /* webpack/runtime/make namespace object */
86714+
/******/ (() => {
86715+
/******/ // define __esModule on exports
86716+
/******/ __nccwpck_require__.r = (exports) => {
86717+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
86718+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
86719+
/******/ }
86720+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
86721+
/******/ };
86722+
/******/ })();
86723+
/******/
8661386724
/******/ /* webpack/runtime/compat */
8661486725
/******/
8661586726
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)