Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add custom cache key and cache restore key input #47

Merged
merged 10 commits into from
Mar 1, 2024
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ jobs:

### Inputs

| **Name** | **Required** | **Default** | **Description** | **Type** |
| --------- | ------------ | ----------- | ------------------------------------------------------------------------------------------------------------ | -------- |
| `cache` | No | `true` | Whether to cache RPC responses or not. | bool |
| `version` | No | `nightly` | Version to install, e.g. `nightly` or `1.0.0`. **Note:** Foundry only has nightly builds for the time being. | string |
| **Name** | **Required** | **Default** | **Description** | **Type** |
| -------------------- | ------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -------- |
| `cache` | No | `true` | Whether to cache RPC responses or not. | bool |
| `version` | No | `nightly` | Version to install, e.g. `nightly` or `1.0.0`. **Note:** Foundry only has nightly builds for the time being. | string |
| `cache-key` | No | `${{ github.job }}-${{ github.sha }}` | The cache key to use for caching. | string |
| `cache-restore-keys` | No | `[${{ github.job }}-]` | The cache keys to use for restoring the cache. | string[] |

### RPC Caching

Expand All @@ -58,6 +60,34 @@ the `cache` input to `false`, like this:
cache: false
```

### Custom Cache Keys

You have the ability to define custom cache keys by utilizing the `cache-key` and `cache-restore-keys` inputs. This
feature is particularly beneficial when you aim to tailor the cache-sharing strategy across multiple jobs. It is
important to ensure that the `cache-key` is unique for each execution to prevent conflicts and guarantee successful
cache saving.

For instance, if you wish to utilize a shared cache between two distinct jobs, the following configuration can be
applied:

```yml
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
cache-key: custom-seed-test-${{ github.sha }}
cache-restore-keys: |-
custom-seed-test-
custom-seed-
---
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
cache-key: custom-seed-coverage-${{ github.sha }}
cache-restore-keys: |-
custom-seed-coverage-
custom-seed-
```

#### Deleting Caches

You can delete caches via the GitHub Actions user interface. Just go to your repo's "Actions" page:
Expand Down
15 changes: 15 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ inputs:

Caching is activated by default.
required: false
cache-key:
default: "${{ github.job }}-${{ github.sha }}"
description: |
A custom cache key to use.

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.
required: false
cache-restore-keys:
default: |-
${{ github.job }}-
description: |
Custom cache restore keys to use.

This key is used to identify the cache to restore. If not provided, a default key consisting of the job id is used.
required: false
version:
default: "nightly"
description: |
Expand Down
88 changes: 82 additions & 6 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86178,32 +86178,63 @@ const github = __nccwpck_require__(5438);
const fs = __nccwpck_require__(7147);
const os = __nccwpck_require__(2037);
const path = __nccwpck_require__(1017);
const { State } = __nccwpck_require__(4438);

const HOME = os.homedir();
const PLATFORM = os.platform();
const CACHE_PATHS = [path.join(HOME, ".foundry/cache/rpc")];

async function restoreRPCCache() {
const primaryKey = PLATFORM + "-foundry-chain-fork-" + github.context.sha;
const restoreKeys = [PLATFORM + "-foundry-chain-fork-"];
const cacheKey = await cache.restoreCache(CACHE_PATHS, primaryKey, restoreKeys);
if (!cacheKey) {
const prefix = `${PLATFORM}-foundry-chain-fork-`;
const customKeyInput = core.getInput("cache-key");
const primaryKey = `${prefix}${customKeyInput}`;
core.saveState(State.CachePrimaryKey, primaryKey);
const defaultRestoreKeys = [prefix];
const customRestoreKeyInput = core
.getInput("cache-restore-keys")
.split(/[\r\n]/)
.map((input) => input.trim())
.filter((input) => input !== "")
.map((input) => `${prefix}${input}`);
const restoreKeys = customRestoreKeyInput.concat(defaultRestoreKeys);
const matchedKey = await cache.restoreCache(CACHE_PATHS, primaryKey, restoreKeys);
if (!matchedKey) {
core.info("Cache not found");
return;
}
core.info(`Cache restored from key: ${cacheKey}`);
core.saveState(State.CacheMatchedKey, matchedKey);
core.info(`Cache restored from key: ${matchedKey}`);
}

async function saveCache() {
const primaryKey = PLATFORM + "-foundry-chain-fork-" + github.context.sha;
const primaryKey = core.getState(State.CachePrimaryKey);
const matchedKey = core.getState(State.CacheMatchedKey);

// If the cache path does not exist, do not save the cache
if (!fs.existsSync(CACHE_PATHS[0])) {
core.info(`Cache path does not exist, not saving cache : ${CACHE_PATHS[0]}`);
return;
}

// If the primary key is not generated, do not save the cache
if (!primaryKey) {
core.info("Primary key was not generated. Please check the log messages above for more errors or information");
return;
}

// If the primary key and the matched key are the same, this means the cache was already saved
if (primaryKey === matchedKey) {
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
return;
}

const cacheId = await cache.saveCache(CACHE_PATHS, primaryKey);

// If the cacheId is -1, the saving failed with an error message log. No additional logging is needed.
if (cacheId === -1) {
return;
}

core.info(`Cache saved with the key: ${primaryKey}`);
}

Expand All @@ -86213,6 +86244,23 @@ module.exports = {
};


/***/ }),

/***/ 4438:
/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {

"use strict";
__nccwpck_require__.r(__webpack_exports__);
/* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
/* harmony export */ "State": () => (/* binding */ State)
/* harmony export */ });
// Enum for the cache primary key and result key.
const State = {
CachePrimaryKey: "CACHE_KEY",
CacheMatchedKey: "CACHE_RESULT",
};


/***/ }),

/***/ 4351:
Expand Down Expand Up @@ -86610,6 +86658,34 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"]
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __nccwpck_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__nccwpck_require__.o(definition, key) && !__nccwpck_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __nccwpck_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __nccwpck_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/compat */
/******/
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

88 changes: 82 additions & 6 deletions dist/save/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84671,32 +84671,63 @@ const github = __nccwpck_require__(5438);
const fs = __nccwpck_require__(7147);
const os = __nccwpck_require__(2037);
const path = __nccwpck_require__(1017);
const { State } = __nccwpck_require__(4438);

const HOME = os.homedir();
const PLATFORM = os.platform();
const CACHE_PATHS = [path.join(HOME, ".foundry/cache/rpc")];

async function restoreRPCCache() {
const primaryKey = PLATFORM + "-foundry-chain-fork-" + github.context.sha;
const restoreKeys = [PLATFORM + "-foundry-chain-fork-"];
const cacheKey = await cache.restoreCache(CACHE_PATHS, primaryKey, restoreKeys);
if (!cacheKey) {
const prefix = `${PLATFORM}-foundry-chain-fork-`;
const customKeyInput = core.getInput("cache-key");
const primaryKey = `${prefix}${customKeyInput}`;
core.saveState(State.CachePrimaryKey, primaryKey);
const defaultRestoreKeys = [prefix];
const customRestoreKeyInput = core
.getInput("cache-restore-keys")
.split(/[\r\n]/)
.map((input) => input.trim())
.filter((input) => input !== "")
.map((input) => `${prefix}${input}`);
const restoreKeys = customRestoreKeyInput.concat(defaultRestoreKeys);
const matchedKey = await cache.restoreCache(CACHE_PATHS, primaryKey, restoreKeys);
if (!matchedKey) {
core.info("Cache not found");
return;
}
core.info(`Cache restored from key: ${cacheKey}`);
core.saveState(State.CacheMatchedKey, matchedKey);
core.info(`Cache restored from key: ${matchedKey}`);
}

async function saveCache() {
const primaryKey = PLATFORM + "-foundry-chain-fork-" + github.context.sha;
const primaryKey = core.getState(State.CachePrimaryKey);
const matchedKey = core.getState(State.CacheMatchedKey);

// If the cache path does not exist, do not save the cache
if (!fs.existsSync(CACHE_PATHS[0])) {
core.info(`Cache path does not exist, not saving cache : ${CACHE_PATHS[0]}`);
return;
}

// If the primary key is not generated, do not save the cache
if (!primaryKey) {
core.info("Primary key was not generated. Please check the log messages above for more errors or information");
return;
}

// If the primary key and the matched key are the same, this means the cache was already saved
if (primaryKey === matchedKey) {
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
return;
}

const cacheId = await cache.saveCache(CACHE_PATHS, primaryKey);

// If the cacheId is -1, the saving failed with an error message log. No additional logging is needed.
if (cacheId === -1) {
return;
}

core.info(`Cache saved with the key: ${primaryKey}`);
}

Expand All @@ -84706,6 +84737,23 @@ module.exports = {
};


/***/ }),

/***/ 4438:
/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {

"use strict";
__nccwpck_require__.r(__webpack_exports__);
/* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
/* harmony export */ "State": () => (/* binding */ State)
/* harmony export */ });
// Enum for the cache primary key and result key.
const State = {
CachePrimaryKey: "CACHE_KEY",
CacheMatchedKey: "CACHE_RESULT",
};


/***/ }),

/***/ 2877:
Expand Down Expand Up @@ -85013,6 +85061,34 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"]
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __nccwpck_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__nccwpck_require__.o(definition, key) && !__nccwpck_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __nccwpck_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __nccwpck_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/compat */
/******/
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
Expand Down
2 changes: 1 addition & 1 deletion dist/save/index.js.map

Large diffs are not rendered by default.

Loading
Loading