Skip to content

Commit 63fce43

Browse files
committed
Add save and restore methods
1 parent 78ab5c2 commit 63fce43

File tree

1 file changed

+117
-1
lines changed

1 file changed

+117
-1
lines changed

src/overlay/status.ts

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,124 @@
88
* We use the Actions cache as a lightweight way of providing this functionality.
99
*/
1010

11+
import * as fs from "fs";
12+
import * as path from "path";
13+
14+
import * as actionsCache from "@actions/cache";
15+
16+
import { getTemporaryDirectory } from "../actions-util";
1117
import { type CodeQL } from "../codeql";
12-
import { DiskUsage } from "../util";
18+
import { Logger } from "../logging";
19+
import {
20+
DiskUsage,
21+
getErrorMessage,
22+
waitForResultWithTimeLimit,
23+
} from "../util";
24+
25+
/** The maximum time to wait for a cache operation to complete. */
26+
const MAX_CACHE_OPERATION_MS = 30_000;
27+
28+
/** File name for the serialized overlay status. */
29+
const STATUS_FILE_NAME = "overlay-status.json";
30+
31+
/** Status of an overlay analysis for a particular language. */
32+
export interface OverlayStatus {
33+
/** Whether the job successfully built an overlay base database. */
34+
builtOverlayBaseDatabase: boolean;
35+
}
36+
37+
/**
38+
* Retrieve overlay status from the Actions cache, if available.
39+
*
40+
* @returns `undefined` if no status was found in the cache (e.g. first run with
41+
* this cache key) or if the cache operation fails.
42+
*/
43+
export async function getOverlayStatus(
44+
codeql: CodeQL,
45+
language: string,
46+
diskUsage: DiskUsage,
47+
logger: Logger,
48+
): Promise<OverlayStatus | undefined> {
49+
const cacheKey = await getCacheKey(codeql, language, diskUsage);
50+
const statusFile = path.join(
51+
getTemporaryDirectory(),
52+
"overlay-status",
53+
language,
54+
STATUS_FILE_NAME,
55+
);
56+
await fs.promises.mkdir(path.dirname(statusFile), { recursive: true });
57+
58+
try {
59+
const foundKey = await waitForResultWithTimeLimit(
60+
MAX_CACHE_OPERATION_MS,
61+
actionsCache.restoreCache([statusFile], cacheKey),
62+
() => {
63+
logger.info("Timed out restoring overlay status from cache");
64+
},
65+
);
66+
if (foundKey === undefined) {
67+
logger.debug("No overlay status found in Actions cache");
68+
return undefined;
69+
}
70+
71+
if (!fs.existsSync(statusFile)) {
72+
logger.debug(
73+
"Overlay status cache entry found but status file is missing",
74+
);
75+
return undefined;
76+
}
77+
78+
const contents = await fs.promises.readFile(statusFile, "utf-8");
79+
return JSON.parse(contents) as OverlayStatus;
80+
} catch (error) {
81+
logger.warning(
82+
`Failed to restore overlay status from cache: ${getErrorMessage(error)}`,
83+
);
84+
return undefined;
85+
}
86+
}
87+
88+
/**
89+
* Save overlay status to the Actions cache.
90+
*
91+
* @returns `true` if the status was saved successfully, `false` otherwise.
92+
*/
93+
export async function saveOverlayStatus(
94+
codeql: CodeQL,
95+
language: string,
96+
diskUsage: DiskUsage,
97+
status: OverlayStatus,
98+
logger: Logger,
99+
): Promise<boolean> {
100+
const cacheKey = await getCacheKey(codeql, language, diskUsage);
101+
const statusFile = path.join(
102+
getTemporaryDirectory(),
103+
"overlay-status",
104+
language,
105+
STATUS_FILE_NAME,
106+
);
107+
await fs.promises.mkdir(path.dirname(statusFile), { recursive: true });
108+
await fs.promises.writeFile(statusFile, JSON.stringify(status));
109+
110+
try {
111+
const cacheId = await waitForResultWithTimeLimit(
112+
MAX_CACHE_OPERATION_MS,
113+
actionsCache.saveCache([statusFile], cacheKey),
114+
() => {},
115+
);
116+
if (cacheId === undefined) {
117+
logger.warning("Timed out saving overlay status to cache");
118+
return false;
119+
}
120+
logger.info(`Saved overlay status to Actions cache with key ${cacheKey}`);
121+
return true;
122+
} catch (error) {
123+
logger.warning(
124+
`Failed to save overlay status to cache: ${getErrorMessage(error)}`,
125+
);
126+
return false;
127+
}
128+
}
13129

14130
export async function getCacheKey(
15131
codeql: CodeQL,

0 commit comments

Comments
 (0)