diff --git a/__tests__/cache.test.itg.ts b/__tests__/cache.test.itg.ts new file mode 100644 index 0000000..ad295f7 --- /dev/null +++ b/__tests__/cache.test.itg.ts @@ -0,0 +1,40 @@ +/** + * Copyright 2024 actions-toolkit authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import path from 'path'; +import {describe, expect, it} from '@jest/globals'; + +import {Cache} from '../src/cache'; + +// prettier-ignore +const tmpDir = path.join(process.env.TEMP || '/tmp', 'cache-jest'); + +const fixturesDir = path.join(__dirname, 'fixtures'); + +describe('cache', () => { + it('github-repo', async () => { + const r = (Math.random() + 1).toString(36).substring(7); + const htcName = `cache-test-github-repo-${r}`; + const c = new Cache({ + htcName: htcName, + htcVersion: `v1.0.0+${r}`, + baseCacheDir: path.join(tmpDir, '.cache-test'), + cacheFile: 'github-repo.json' + }); + expect(await c.save(path.join(fixturesDir, 'github-repo.json'))).not.toEqual(''); + expect(await c.find()).not.toEqual(''); + }); +}); diff --git a/src/cache.ts b/src/cache.ts index 1baa623..0aa069a 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -30,6 +30,11 @@ export interface CacheOpts { ghaNoCache?: boolean; } +export interface CachePostState { + dir: string; + key: string; +} + export class Cache { private readonly opts: CacheOpts; private readonly ghaCacheKey: string; @@ -37,6 +42,8 @@ export class Cache { private readonly cacheDir: string; private readonly cachePath: string; + private static readonly POST_CACHE_KEY = 'postCache'; + constructor(opts: CacheOpts) { this.opts = opts; this.ghaCacheKey = util.format('%s-%s-%s', this.opts.htcName, this.opts.htcVersion, this.platform()); @@ -56,8 +63,14 @@ export class Cache { core.debug(`Cache.save cached to hosted tool cache ${htcPath}`); if (!this.ghaNoCache && cache.isFeatureAvailable()) { - core.debug(`Cache.save caching ${this.ghaCacheKey} to GitHub Actions cache`); - await cache.saveCache([this.cacheDir], this.ghaCacheKey); + core.debug(`Cache.save sending ${this.ghaCacheKey} to post state`); + core.saveState( + Cache.POST_CACHE_KEY, + JSON.stringify({ + dir: this.cacheDir, + key: this.ghaCacheKey + } as CachePostState) + ); } return cachePath; @@ -75,7 +88,7 @@ export class Cache { if (await cache.restoreCache([this.cacheDir], this.ghaCacheKey)) { core.info(`Restored ${this.ghaCacheKey} from GitHub Actions cache`); htcPath = await tc.cacheDir(this.cacheDir, this.opts.htcName, this.opts.htcVersion, this.platform()); - core.info(`Restored to hosted tool cache ${htcPath}`); + core.info(`Cached to hosted tool cache ${htcPath}`); return this.copyToCache(`${htcPath}/${this.opts.cacheFile}`); } } else if (this.ghaNoCache) { @@ -87,6 +100,26 @@ export class Cache { return ''; } + public static async post(): Promise { + const state = core.getState(Cache.POST_CACHE_KEY); + if (!state) { + core.debug(`Cache.post no state`); + return Promise.resolve(undefined); + } + let cacheState: CachePostState; + try { + cacheState = JSON.parse(state); + } catch (e) { + throw new Error(`Failed to parse cache post state: ${e}`); + } + if (!cacheState.dir || !cacheState.key) { + throw new Error(`Invalid cache post state: ${state}`); + } + core.info(`Caching ${cacheState.key} to GitHub Actions cache`); + await cache.saveCache([cacheState.dir], cacheState.key); + return cacheState; + } + private copyToCache(file: string): string { core.debug(`Copying ${file} to ${this.cachePath}`); fs.copyFileSync(file, this.cachePath); diff --git a/src/index.ts b/src/index.ts index 8d02199..c43fe48 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,6 +16,8 @@ import * as core from '@actions/core'; +import {Cache} from './cache'; + const isPost = !!process.env['STATE_isPost']; if (!isPost) { core.saveState('isPost', 'true'); @@ -36,7 +38,10 @@ export async function run(main: () => Promise, post?: () => Promise) } catch (e) { core.setFailed(e.message); } - } else if (post) { - await post(); + } else { + if (post) { + await post(); + } + await Cache.post(); } }