mirror of
https://github.com/github/codeql-action.git
synced 2026-01-02 20:50:05 +08:00
TRAP Caching: Skip uploading of small caches
This commit is contained in:
@@ -165,6 +165,7 @@ test("upload cache key contains right fields", async (t) => {
|
||||
const loggedMessages = [];
|
||||
const logger = getRecordingLogger(loggedMessages);
|
||||
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
sinon.stub(util, "tryGetFolderBytes").resolves(999_999_999);
|
||||
const stubSave = sinon.stub(cache, "saveCache");
|
||||
process.env.GITHUB_SHA = "somesha";
|
||||
await uploadTrapCaches(stubCodeql, testConfigWithoutTmpDir, logger);
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { promisify } from "util";
|
||||
|
||||
import * as cache from "@actions/cache";
|
||||
import getFolderSize from "get-folder-size";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { CodeQL, CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { codeQlVersionAbove } from "./util";
|
||||
import { codeQlVersionAbove, tryGetFolderBytes } from "./util";
|
||||
|
||||
// This constant should be bumped if we make a breaking change
|
||||
// to how the CodeQL Action stores or retrieves the TRAP cache,
|
||||
@@ -22,6 +20,10 @@ const CACHE_VERSION = 1;
|
||||
// This constant sets the size of each TRAP cache in megabytes.
|
||||
const CACHE_SIZE_MB = 1024;
|
||||
|
||||
// This constant sets the minimum size in megabytes of a TRAP
|
||||
// cache for us to consider it worth uploading.
|
||||
const MINIMUM_CACHE_MB_TO_UPLOAD = 10;
|
||||
|
||||
export async function getTrapCachingExtractorConfigArgs(
|
||||
config: Config
|
||||
): Promise<string[]> {
|
||||
@@ -138,6 +140,19 @@ export async function uploadTrapCaches(
|
||||
for (const language of config.languages) {
|
||||
const cacheDir = config.trapCaches[language];
|
||||
if (cacheDir === undefined) continue;
|
||||
const trapFolderSize = await tryGetFolderBytes(cacheDir, logger);
|
||||
if (trapFolderSize === undefined) {
|
||||
logger.info(
|
||||
`Skipping upload of TRAP cache for ${language} as we couldn't determine its size`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (trapFolderSize < MINIMUM_CACHE_MB_TO_UPLOAD * 1_048_576) {
|
||||
logger.info(
|
||||
`Skipping upload of TRAP cache for ${language} as it is too small`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
const key = await cacheKey(
|
||||
codeql,
|
||||
language,
|
||||
@@ -201,17 +216,12 @@ export async function getTotalCacheSize(
|
||||
trapCaches: Partial<Record<Language, string>>,
|
||||
logger: Logger
|
||||
): Promise<number> {
|
||||
try {
|
||||
const sizes = await Promise.all(
|
||||
Object.values(trapCaches).map(async (cacheDir) => {
|
||||
return promisify<string, number>(getFolderSize)(cacheDir);
|
||||
})
|
||||
);
|
||||
return sizes.reduce((a, b) => a + b, 0);
|
||||
} catch (e) {
|
||||
logger.warning(`Encountered an error while getting TRAP cache size: ${e}`);
|
||||
return 0;
|
||||
}
|
||||
const sizes = await Promise.all(
|
||||
Object.values(trapCaches).map((cacheDir) =>
|
||||
tryGetFolderBytes(cacheDir, logger)
|
||||
)
|
||||
);
|
||||
return sizes.map((a) => a || 0).reduce((a, b) => a + b, 0);
|
||||
}
|
||||
|
||||
async function cacheKey(
|
||||
|
||||
22
src/util.ts
22
src/util.ts
@@ -2,9 +2,11 @@ import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import { Readable } from "stream";
|
||||
import { promisify } from "util";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import del from "del";
|
||||
import getFolderSize from "get-folder-size";
|
||||
import * as semver from "semver";
|
||||
|
||||
import * as api from "./api-client";
|
||||
@@ -836,3 +838,23 @@ export async function isGoExtractionReconciliationEnabled(
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size a folder in bytes. This will log any filesystem errors
|
||||
* as a warning and then return undefined.
|
||||
*
|
||||
* @param cacheDir A directory to get the size of.
|
||||
* @param logger A logger to log any errors to.
|
||||
* @returns The size in bytes of the folder, or undefined if errors occurred.
|
||||
*/
|
||||
export async function tryGetFolderBytes(
|
||||
cacheDir: string,
|
||||
logger: Logger
|
||||
): Promise<number | undefined> {
|
||||
try {
|
||||
return await promisify<string, number>(getFolderSize)(cacheDir);
|
||||
} catch (e) {
|
||||
logger.warning(`Encountered an error while getting size of folder: ${e}`);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user