Download overlay-base database from actions cache

This commit is contained in:
Chuan-kai Lin
2025-06-17 08:09:39 -07:00
parent b95402dae1
commit 2fc04c80cc
2 changed files with 116 additions and 1 deletions

View File

@@ -42,7 +42,10 @@ import {
} from "./init";
import { Language } from "./languages";
import { getActionsLogger, Logger } from "./logging";
import { OverlayDatabaseMode } from "./overlay-database-utils";
import {
downloadOverlayBaseDatabaseFromCache,
OverlayDatabaseMode,
} from "./overlay-database-utils";
import { getRepositoryNwo } from "./repository";
import { ToolsSource } from "./setup-codeql";
import {
@@ -398,6 +401,34 @@ async function run() {
}
try {
if (
config.augmentationProperties.overlayDatabaseMode ===
OverlayDatabaseMode.Overlay &&
config.augmentationProperties.useOverlayDatabaseCaching
) {
// OverlayDatabaseMode.Overlay comes in two flavors: with database
// caching, or without. The flavor with database caching is intended to be
// an "automatic control" mode, which is supposed to be fail-safe. If we
// cannot download an overlay-base database, we revert to
// OverlayDatabaseMode.None so that the workflow can continue to run.
//
// The flavor without database caching is intended to be a "manual
// control" mode, where the workflow is supposed to make all the
// necessary preparations. So, in that mode, we would assume that
// everything is in order and let the analysis fail if that turns out not
// to be the case.
const overlayDatabaseDownloaded =
await downloadOverlayBaseDatabaseFromCache(codeql, config, logger);
if (!overlayDatabaseDownloaded) {
config.augmentationProperties.overlayDatabaseMode =
OverlayDatabaseMode.None;
logger.info(
"No overlay-base database found in cache, " +
`reverting overlay database mode to ${OverlayDatabaseMode.None}.`,
);
}
}
if (
config.augmentationProperties.overlayDatabaseMode !==
OverlayDatabaseMode.Overlay

View File

@@ -235,6 +235,90 @@ export async function uploadOverlayBaseDatabaseToCache(
return true;
}
/**
* Downloads the overlay-base database from the GitHub Actions cache. If conditions
* for downloading are not met, the function does nothing and returns false.
*
* @param codeql The CodeQL instance
* @param config The configuration object
* @param logger The logger instance
* @returns A promise that resolves to true if the download was performed and
* successfully completed, or false otherwise
*/
export async function downloadOverlayBaseDatabaseFromCache(
codeql: CodeQL,
config: Config,
logger: Logger,
): Promise<boolean> {
const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode;
if (overlayDatabaseMode !== OverlayDatabaseMode.Overlay) {
logger.debug(
`Overlay database mode is ${overlayDatabaseMode}. ` +
"Skip downloading overlay-base database from cache.",
);
return false;
}
if (!config.augmentationProperties.useOverlayDatabaseCaching) {
logger.debug(
"Overlay database caching is disabled. " +
"Skip downloading overlay-base database from cache.",
);
return false;
}
if (isInTestMode()) {
logger.debug(
"In test mode. Skip downloading overlay-base database from cache.",
);
return false;
}
const dbLocation = config.dbLocation;
const codeQlVersion = (await codeql.getVersion()).version;
const restoreKey = getCacheRestoreKey(config, codeQlVersion);
logger.info(
`Looking in Actions cache for overlay-base database with restore key ${restoreKey}`,
);
try {
const foundKey = await withTimeout(
MAX_CACHE_OPERATION_MS,
actionsCache.restoreCache([dbLocation], restoreKey),
() => {
logger.info("Timed out downloading overlay-base database from cache");
},
);
if (foundKey === undefined) {
logger.info("No overlay-base database found in Actions cache");
return false;
}
logger.info(
`Downloaded overlay-base database in cache with key ${foundKey}`,
);
} catch (error) {
logger.warning(
"Failed to download overlay-base database from cache: " +
`${error instanceof Error ? error.message : String(error)}`,
);
return false;
}
const databaseIsValid = checkOverlayBaseDatabase(
config,
logger,
"Downloaded overlay-base database is invalid",
);
if (!databaseIsValid) {
logger.warning("Downloaded overlay-base database failed validation");
return false;
}
logger.info(`Successfully downloaded overlay-base database to ${dbLocation}`);
return true;
}
async function generateCacheKey(
config: Config,
codeQlVersion: string,