diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 48f1ccb..20d22f7 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -53,6 +53,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] + reeval: [false, true] fail-fast: false runs-on: ${{ matrix.os }} steps: @@ -67,10 +68,36 @@ jobs: - name: Save cache uses: ./ with: - key: test-${{ runner.os }}-${{ github.run_id }} + reeval: ${{ matrix.reeval }} + key: test-${{ runner.os }}-${{ github.run_id }}-${{ matrix.reeval }} path: | test-cache ~/test-cache + test-only-restore: + needs: test-save + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + fail-fast: false + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Restore cache + uses: ./ + with: + only-restore: true + reeval: ${{ matrix.reeval }} + key: test-${{ runner.os }}-${{ github.run_id }}-${{ matrix.reeval }} + path: | + test-cache + ~/test-cache + - name: Verify cache files in working directory + shell: bash + run: __tests__/verify-cache-files.sh ${{ runner.os }} test-cache + - name: Verify cache files outside working directory + shell: bash + run: __tests__/verify-cache-files.sh ${{ runner.os }} ~/test-cache test-restore: needs: test-save strategy: @@ -84,7 +111,8 @@ jobs: - name: Restore cache uses: ./ with: - key: test-${{ runner.os }}-${{ github.run_id }} + reeval: ${{ matrix.reeval }} + key: test-${{ runner.os }}-${{ github.run_id }}-${{ matrix.reeval }} path: | test-cache ~/test-cache @@ -97,6 +125,9 @@ jobs: # End to end with proxy test-proxy-save: + strategy: + matrix: + reeval: [false, true] runs-on: ubuntu-latest container: image: ubuntu:latest @@ -116,10 +147,14 @@ jobs: - name: Save cache uses: ./ with: - key: test-proxy-${{ github.run_id }} + reeval: ${{ matrix.reeval }} + key: test-proxy-${{ github.run_id }}-${{ matrix.reeval }} path: test-cache - test-proxy-restore: + test-proxy-only-restore: needs: test-proxy-save + strategy: + matrix: + reeval: [false, true] runs-on: ubuntu-latest container: image: ubuntu:latest @@ -137,7 +172,36 @@ jobs: - name: Restore cache uses: ./ with: - key: test-proxy-${{ github.run_id }} + only-restore: true + reeval: ${{ matrix.reeval }} + key: test-proxy-${{ github.run_id }}-${{ matrix.reeval }} + path: test-cache + - name: Verify cache + run: __tests__/verify-cache-files.sh proxy test-cache + test-proxy-restore: + needs: test-proxy-save + strategy: + matrix: + reeval: [false, true] + runs-on: ubuntu-latest + container: + image: ubuntu:latest + options: --dns 127.0.0.1 + services: + squid-proxy: + image: datadog/squid:latest + ports: + - 3128:3128 + env: + https_proxy: http://squid-proxy:3128 + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Restore cache + uses: ./ + with: + reeval: ${{ matrix.reeval }} + key: test-proxy-${{ github.run_id }}-${{ matrix.reeval }} path: test-cache - name: Verify cache run: __tests__/verify-cache-files.sh proxy test-cache diff --git a/.gitignore b/.gitignore index fda65d8..977c2c3 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,6 @@ typings/ # Text editor files .vscode/ + +# OS +.DS_Store diff --git a/action.yml b/action.yml index 3e158e3..99cd388 100644 --- a/action.yml +++ b/action.yml @@ -14,6 +14,14 @@ inputs: upload-chunk-size: description: 'The chunk size used to split up large files during upload, in bytes' required: false + reeval: + description: "Boolean. Whether to reevaluate the key argument in post. Set to TRUE if you would like your cache key set after your job's steps are complete." + required: false + default: false + only-restore: + description: 'Boolean. Whether to only perform cache restoration and NOT the save post run step.' + required: false + default: false outputs: cache-hit: description: 'A boolean value to indicate an exact match was found for the primary key' diff --git a/dist/restore/index.js b/dist/restore/index.js index 9351a66..a1bc1b5 100644 --- a/dist/restore/index.js +++ b/dist/restore/index.js @@ -4607,7 +4607,9 @@ exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inpu var Inputs; (function (Inputs) { Inputs["Key"] = "key"; + Inputs["OnlyRestore"] = "only-restore"; Inputs["Path"] = "path"; + Inputs["Reeval"] = "reeval"; Inputs["RestoreKeys"] = "restore-keys"; Inputs["UploadChunkSize"] = "upload-chunk-size"; })(Inputs = exports.Inputs || (exports.Inputs = {})); diff --git a/dist/save/index.js b/dist/save/index.js index 983cb5d..e3153a0 100644 --- a/dist/save/index.js +++ b/dist/save/index.js @@ -4607,7 +4607,9 @@ exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inpu var Inputs; (function (Inputs) { Inputs["Key"] = "key"; + Inputs["OnlyRestore"] = "only-restore"; Inputs["Path"] = "path"; + Inputs["Reeval"] = "reeval"; Inputs["RestoreKeys"] = "restore-keys"; Inputs["UploadChunkSize"] = "upload-chunk-size"; })(Inputs = exports.Inputs || (exports.Inputs = {})); @@ -46770,49 +46772,60 @@ const utils = __importStar(__webpack_require__(443)); process.on("uncaughtException", e => utils.logWarning(e.message)); function run() { 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; - } - 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); - 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 save = !core.getBooleanInput(constants_1.Inputs.OnlyRestore); + if (save) { try { - yield cache.saveCache(cachePaths, primaryKey, { - uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize) - }); - core.info(`Cache saved with key: ${primaryKey}`); - } - catch (error) { - const typedError = error; - if (typedError.name === cache.ValidationError.name) { - throw error; + if (!utils.isCacheFeatureAvailable()) { + return; } - else if (typedError.name === cache.ReserveCacheError.name) { - core.info(typedError.message); + 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(); + let primaryKey = ""; + const reeval = core.getBooleanInput(constants_1.Inputs.Reeval); + if (!reeval) { + // Inputs are reevaluted before the post action, so we want the original key used for restore + primaryKey = core.getState(constants_1.State.CachePrimaryKey); } else { - utils.logWarning(typedError.message); + // choose to reevaluate primary key + primaryKey = core.getInput(constants_1.Inputs.Key, { required: true }); + } + 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 + }); + try { + yield cache.saveCache(cachePaths, primaryKey, { + uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize) + }); + 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); + catch (error) { + utils.logWarning(error.message); + } } }); } diff --git a/src/constants.ts b/src/constants.ts index 133f47d..6d2ec97 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,6 +1,8 @@ export enum Inputs { Key = "key", + OnlyRestore = "only-restore", Path = "path", + Reeval = "reeval", RestoreKeys = "restore-keys", UploadChunkSize = "upload-chunk-size" } diff --git a/src/save.ts b/src/save.ts index 7b333fb..df2fe4a 100644 --- a/src/save.ts +++ b/src/save.ts @@ -10,57 +10,67 @@ import * as utils from "./utils/actionUtils"; process.on("uncaughtException", e => utils.logWarning(e.message)); async function run(): Promise { - 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; - } - - 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); - 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 save = !core.getBooleanInput(Inputs.OnlyRestore); + if (save) { try { - await cache.saveCache(cachePaths, primaryKey, { - uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize) - }); - 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); + 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(); + + let primaryKey = ""; + const reeval = core.getBooleanInput(Inputs.Reeval); + if (!reeval) { + // Inputs are reevaluted before the post action, so we want the original key used for restore + primaryKey = core.getState(State.CachePrimaryKey); + } else { + // choose to reevaluate primary key + primaryKey = core.getInput(Inputs.Key, { required: true }); + } + 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 + }); + + try { + await cache.saveCache(cachePaths, primaryKey, { + uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize) + }); + 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); } - } catch (error: unknown) { - utils.logWarning((error as Error).message); } }