diff --git a/README.md b/README.md index 9813a6b..cf5a70d 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ order to determine the repo state. | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------- | | bucket-name | Name of the S3 bucket to use for storing cache files. The job needs to have AWS credentials configured to allow read/write from this bucket. | `true` | | | key-prefix | Key prefix to add to the cache files key. By default the job ID is used. The full key used for the cache files is `cache/${repoOwner}/${repoName}/${keyPrefix}/${treeHash}` | `false` | ${{ github.job }} | +| custom-hash | Hash calculated on the user's side used as part of the cache key for the job run. | `false` | | | aws-region | AWS region for the S3 bucket used for cache files. available. | `true` | | | aws-access-key-id | Access Key ID for an IAM user with permissions to read/write to the S3 bucket used for cache files. | `true` | | | aws-secret-access-key | Secret Access Key for an IAM user with permissions to read/write to the S3 bucket used for cache files. | `true` | | diff --git a/action.yml b/action.yml index cda3429..6c318a1 100644 --- a/action.yml +++ b/action.yml @@ -14,6 +14,10 @@ inputs: used for the cache files is `cache/${repoOwner}/${repoName}/${keyPrefix}/${treeHash}` default: ${{ github.job }} required: false + custom-hash: + description: + Hash calculated on the user's side used as part of the cache key for the job run. + required: false aws-region: description: AWS region for the S3 bucket used for cache files. available. required: true diff --git a/dist/restore/index.js b/dist/restore/index.js index 7957e1a..7c6a1eb 100644 --- a/dist/restore/index.js +++ b/dist/restore/index.js @@ -10821,13 +10821,14 @@ const utils_1 = __nccwpck_require__(1314); (0, utils_1.runAction)(() => __awaiter(void 0, void 0, void 0, function* () { const bucket = (0, core_1.getInput)('bucket-name', { required: true }); const keyPrefix = (0, core_1.getInput)('key-prefix'); + const customHash = (0, core_1.getInput)('custom-hash'); const repo = github.context.repo; const awsOptions = { region: (0, core_1.getInput)('aws-region'), accessKeyId: (0, core_1.getInput)('aws-access-key-id'), secretAccessKey: (0, core_1.getInput)('aws-secret-access-key') }; - const output = yield restoreS3Cache({ bucket, keyPrefix, repo, awsOptions }); + const output = yield restoreS3Cache({ bucket, keyPrefix, customHash, repo, awsOptions }); // Saving key and hash in "state" which can be retrieved by the // "post" run of the action (save.ts) // https://github.com/actions/toolkit/tree/daf8bb00606d37ee2431d9b1596b88513dcf9c59/packages/core#action-state @@ -10836,9 +10837,10 @@ const utils_1 = __nccwpck_require__(1314); (0, core_1.setOutput)('processed', output.processed); (0, core_1.setOutput)('hash', output.treeHash); })); -function restoreS3Cache({ bucket, keyPrefix, repo, awsOptions }) { +function restoreS3Cache({ bucket, keyPrefix, customHash, repo, awsOptions }) { return __awaiter(this, void 0, void 0, function* () { - const treeHash = yield (0, utils_1.getCurrentRepoTreeHash)(); + const currentRepoTreeHash = yield (0, utils_1.getCurrentRepoTreeHash)(); + const treeHash = customHash || currentRepoTreeHash; const key = `cache/${repo.owner}/${repo.repo}/${keyPrefix}/${treeHash}`; const fileExists = yield (0, utils_1.fileExistsInS3)({ key, bucket, awsOptions }); if (fileExists) { diff --git a/src/restore.test.ts b/src/restore.test.ts index 07d7664..7ef4197 100644 --- a/src/restore.test.ts +++ b/src/restore.test.ts @@ -75,4 +75,27 @@ describe(`S3 Cache Action - Restore cache`, () => { }) } ) + + test( + strip` + When a custom hash is provided + Then it should use the custom hash instead of the auto-generated one + `, + async () => { + const treeHash = 'cba2d570993b9c21e3de282e5ba56d1638fb32de' + const customHash = '070e5b3591d571974f31f594d6f841ea' + mockedUtils.getCurrentRepoTreeHash.mockResolvedValue(treeHash) + mockedUtils.fileExistsInS3.mockResolvedValue(true) + + const output = await restoreS3Cache({ + bucket: 'my-other-bucket', + keyPrefix: 'horse', + repo: {owner: 'my-org', repo: 'my-repo'}, + awsOptions, + customHash + }) + + expect(output.treeHash).toBe(customHash) + } + ) }) diff --git a/src/restore.ts b/src/restore.ts index 1a9abe0..b935ab0 100644 --- a/src/restore.ts +++ b/src/restore.ts @@ -13,6 +13,7 @@ import {getCurrentRepoTreeHash, fileExistsInS3, runAction, AWSOptions} from './u runAction(async () => { const bucket = getInput('bucket-name', {required: true}) const keyPrefix = getInput('key-prefix') + const customHash = getInput('custom-hash') const repo = github.context.repo const awsOptions = { region: getInput('aws-region'), @@ -20,7 +21,7 @@ runAction(async () => { secretAccessKey: getInput('aws-secret-access-key') } - const output = await restoreS3Cache({bucket, keyPrefix, repo, awsOptions}) + const output = await restoreS3Cache({bucket, keyPrefix, customHash, repo, awsOptions}) // Saving key and hash in "state" which can be retrieved by the // "post" run of the action (save.ts) @@ -35,6 +36,7 @@ runAction(async () => { type RestoreS3CacheActionArgs = { bucket: string keyPrefix: string + customHash?: string repo: {owner: string; repo: string} awsOptions: AWSOptions } @@ -42,10 +44,12 @@ type RestoreS3CacheActionArgs = { export async function restoreS3Cache({ bucket, keyPrefix, + customHash, repo, awsOptions }: RestoreS3CacheActionArgs) { - const treeHash = await getCurrentRepoTreeHash() + const currentRepoTreeHash = await getCurrentRepoTreeHash() + const treeHash = customHash || currentRepoTreeHash const key = `cache/${repo.owner}/${repo.repo}/${keyPrefix}/${treeHash}` const fileExists = await fileExistsInS3({key, bucket, awsOptions})