Skip to content

Commit 2f4fb45

Browse files
committed
Download overlay-base database from actions cache
1 parent bdfb816 commit 2f4fb45

File tree

2 files changed

+116
-1
lines changed

2 files changed

+116
-1
lines changed

src/init-action.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ import {
4242
} from "./init";
4343
import { Language } from "./languages";
4444
import { getActionsLogger, Logger } from "./logging";
45-
import { OverlayDatabaseMode } from "./overlay-database-utils";
45+
import {
46+
downloadOverlayBaseDatabaseFromCache,
47+
OverlayDatabaseMode,
48+
} from "./overlay-database-utils";
4649
import { getRepositoryNwo } from "./repository";
4750
import { ToolsSource } from "./setup-codeql";
4851
import {
@@ -394,6 +397,34 @@ async function run() {
394397
}
395398

396399
try {
400+
if (
401+
config.augmentationProperties.overlayDatabaseMode ===
402+
OverlayDatabaseMode.Overlay &&
403+
config.augmentationProperties.useOverlayDatabaseCaching
404+
) {
405+
// OverlayDatabaseMode.Overlay comes in two flavors: with database
406+
// caching, or without. The flavor with database caching is intended to be
407+
// an "automatic control" mode, which is supposed to be fail-safe. If we
408+
// cannot download an overlay-base database, we revert to
409+
// OverlayDatabaseMode.None so that the workflow can continue to run.
410+
//
411+
// The flavor without database caching is intended to be a "manual
412+
// control" mode, where the workflow is supposed to make all the
413+
// necessary preparations. So, in that mode, we would assume that
414+
// everything is in order and let the analysis fail if that turns out not
415+
// to be the case.
416+
const overlayDatabaseDownloaded =
417+
await downloadOverlayBaseDatabaseFromCache(codeql, config, logger);
418+
if (!overlayDatabaseDownloaded) {
419+
config.augmentationProperties.overlayDatabaseMode =
420+
OverlayDatabaseMode.None;
421+
logger.info(
422+
"No overlay-base database found in cache, " +
423+
`reverting overlay database mode to ${OverlayDatabaseMode.None}.`,
424+
);
425+
}
426+
}
427+
397428
if (
398429
config.augmentationProperties.overlayDatabaseMode !==
399430
OverlayDatabaseMode.Overlay

src/overlay-database-utils.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,90 @@ export async function uploadOverlayBaseDatabaseToCache(
230230
return true;
231231
}
232232

233+
/**
234+
* Downloads the overlay-base database from the GitHub Actions cache. If conditions
235+
* for downloading are not met, the function does nothing and returns false.
236+
*
237+
* @param codeql The CodeQL instance
238+
* @param config The configuration object
239+
* @param logger The logger instance
240+
* @returns A promise that resolves to true if the download was performed and
241+
* successfully completed, or false otherwise
242+
*/
243+
export async function downloadOverlayBaseDatabaseFromCache(
244+
codeql: CodeQL,
245+
config: Config,
246+
logger: Logger,
247+
): Promise<boolean> {
248+
const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode;
249+
if (overlayDatabaseMode !== OverlayDatabaseMode.Overlay) {
250+
logger.debug(
251+
`Overlay database mode is ${overlayDatabaseMode}. ` +
252+
"Skip downloading overlay-base database from cache.",
253+
);
254+
return false;
255+
}
256+
if (!config.augmentationProperties.useOverlayDatabaseCaching) {
257+
logger.debug(
258+
"Overlay database caching is disabled. " +
259+
"Skip downloading overlay-base database from cache.",
260+
);
261+
return false;
262+
}
263+
if (isInTestMode()) {
264+
logger.debug(
265+
"In test mode. Skip downloading overlay-base database from cache.",
266+
);
267+
return false;
268+
}
269+
270+
const dbLocation = config.dbLocation;
271+
const codeQlVersion = (await codeql.getVersion()).version;
272+
const restoreKey = getCacheRestoreKey(codeQlVersion);
273+
274+
logger.info(
275+
`Looking in Actions cache for overlay-base database with restore key ${restoreKey}`,
276+
);
277+
278+
try {
279+
const foundKey = await withTimeout(
280+
MAX_CACHE_OPERATION_MS,
281+
actionsCache.restoreCache([dbLocation], restoreKey),
282+
() => {
283+
logger.info("Timed out downloading overlay-base database from cache");
284+
},
285+
);
286+
287+
if (foundKey === undefined) {
288+
logger.info("No overlay-base database found in Actions cache");
289+
return false;
290+
}
291+
292+
logger.info(
293+
`Downloaded overlay-base database in cache with key ${foundKey}`,
294+
);
295+
} catch (error) {
296+
logger.warning(
297+
"Failed to download overlay-base database from cache: " +
298+
`${error instanceof Error ? error.message : String(error)}`,
299+
);
300+
return false;
301+
}
302+
303+
const databaseIsValid = checkOverlayBaseDatabase(
304+
config,
305+
logger,
306+
"Downloaded overlay-base database is invalid",
307+
);
308+
if (!databaseIsValid) {
309+
logger.warning("Downloaded overlay-base database failed validation");
310+
return false;
311+
}
312+
313+
logger.info(`Successfully downloaded overlay-base database to ${dbLocation}`);
314+
return true;
315+
}
316+
233317
function generateCacheKey(codeQlVersion: string): string {
234318
const sha = process.env.GITHUB_SHA || "unknown";
235319
return `${getCacheRestoreKey(codeQlVersion)}${sha}`;

0 commit comments

Comments
 (0)