use highlevel actions cache api for save

This commit is contained in:
Sergey Dolin
2023-07-05 11:06:16 +02:00
parent d8dfea6c6d
commit caeb593a24
6 changed files with 176 additions and 94 deletions

View File

@@ -4,6 +4,7 @@ import path from 'path';
export const downloadFileFromActionsCache = (
destFileName: string,
cacheKey: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
cacheVersion: string
): Promise<void> =>
cache.restoreCache([path.dirname(destFileName)], cacheKey, [

View File

@@ -3,6 +3,7 @@ import * as core from '@actions/core';
import * as cache from '@actions/cache';
import {getOctokit} from '@actions/github';
import {retry as octokitRetry} from '@octokit/plugin-retry';
import path from 'path';
const resetCacheWithOctokit = async (cacheKey: string): Promise<void> => {
const token = core.getInput('repo-token');
@@ -26,6 +27,7 @@ const resetCacheWithOctokit = async (cacheKey: string): Promise<void> => {
export const uploadFileToActionsCache = async (
filePath: string,
cacheKey: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
cacheVersion: string
) => {
await resetCacheWithOctokit(cacheKey);
@@ -36,5 +38,6 @@ export const uploadFileToActionsCache = async (
return;
}
cache.saveCache([filePath], cacheKey);
core.debug('content: ' + fs.readFileSync(filePath).toString());
cache.saveCache([path.dirname(filePath)], cacheKey);
};

View File

@@ -5,6 +5,10 @@ import os from 'os';
import * as core from '@actions/core';
import {downloadFileFromActionsCache} from '../actions-cache-hilevel/download';
import {uploadFileToActionsCache} from '../actions-cache-hilevel/upload';
import * as exec from '@actions/exec';
import {getOctokit} from '@actions/github';
import {retry as octokitRetry} from '@octokit/plugin-retry';
import * as cache from '@actions/cache';
/*
import {uploadFileToActionsCache} from '../actions-cache-internal/upload';
import {downloadFileFromActionsCache} from '../actions-cache-internal/download';
@@ -13,28 +17,108 @@ import {downloadFileFromActionsCache} from '../actions-cache-internal/download';
const CACHE_KEY = '_state';
const CACHE_VERSION = '1';
const STATE_FILE = 'state.txt';
const STALE_DIR = '56acbeaa-1fef-4c79-8f84-7565e560fb03';
const mkTempDir = (): string => {
const tmpDir = path.join(os.tmpdir(), STALE_DIR);
fs.mkdirSync(tmpDir, {recursive: true});
return tmpDir;
};
const unlinkSafely = (filePath: string) => {
try {
fs.unlinkSync(filePath);
} catch (foo) {
/* ignore */
}
};
export const getCommandOutput = async (
toolCommand: string,
cwd?: string
): Promise<string> => {
let {stdout, stderr, exitCode} = await exec.getExecOutput(
toolCommand,
undefined,
{ignoreReturnCode: true, ...(cwd && {cwd})}
);
if (exitCode) {
stderr = !stderr.trim()
? `The '${toolCommand}' command failed with exit code: ${exitCode}`
: stderr;
throw new Error(stderr);
}
return stdout.trim();
};
async function execCommands(commands: string[], cwd?: string): Promise<void> {
for (const command of commands) {
try {
await exec.exec(command, undefined, {cwd});
} catch (error) {
throw new Error(
`${command.split(' ')[0]} failed with error: ${error?.message}`
);
}
}
}
const resetCacheWithOctokit = async (cacheKey: string): Promise<void> => {
const token = core.getInput('repo-token');
const client = getOctokit(token, undefined, octokitRetry);
// TODO: better way to get repository?
const repo = process.env['GITHUB_REPOSITORY'];
core.debug(`remove cache "${cacheKey}"`);
try {
// TODO: replace with client.rest.
await client.request(
`DELETE /repos/${repo}/actions/caches?key=${cacheKey}`
);
} catch (error) {
if (error.status) {
core.debug(`Cache ${cacheKey} does not exist`);
} else {
throw error;
}
}
};
export class StateCacheStorage implements IStateStorage {
async save(serializedState: string): Promise<void> {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'state-'));
const file = path.join(tmpDir, STATE_FILE);
fs.writeFileSync(file, serializedState);
const tmpDir = mkTempDir();
const filePath = path.join(tmpDir, STATE_FILE);
fs.writeFileSync(filePath, serializedState);
try {
await uploadFileToActionsCache(file, CACHE_KEY, CACHE_VERSION);
await resetCacheWithOctokit(CACHE_KEY);
const fileSize = fs.statSync(filePath).size;
if (fileSize === 0) {
core.info(`the cache ${CACHE_KEY} will be removed`);
return;
}
await cache.saveCache([path.dirname(filePath)], CACHE_KEY);
} catch (error) {
core.warning(
`Saving the state was not successful due to "${
error.message || 'unknown reason'
}"`
);
} finally {
unlinkSafely(filePath);
}
}
async restore(): Promise<string> {
const tmpDir = fs.mkdtempSync('state-');
const tmpDir = mkTempDir(); //fs.mkdtempSync('state-');
const fileName = path.join(tmpDir, STATE_FILE);
unlinkSafely(fileName);
try {
await downloadFileFromActionsCache(fileName, CACHE_KEY, CACHE_VERSION);
await execCommands([`ls -la ${path.dirname(fileName)}`]);
if (!fs.existsSync(fileName)) {
core.info(
'The stored state has not been found, probably because of the very first run or the previous run failed'