Refactoring per PR comments

This commit is contained in:
Angela P Wen
2022-08-01 12:52:16 +02:00
parent 8a4a573d59
commit 5da7870265
12 changed files with 316 additions and 312 deletions

View File

@@ -6,17 +6,28 @@ import * as artifact from "@actions/artifact";
import * as core from "@actions/core";
import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as safeWhich from "@chrisgavin/safe-which";
import AdmZip from "adm-zip";
import del from "del";
import * as yaml from "js-yaml";
import { dbIsFinalized } from "./analyze";
import * as api from "./api-client";
import { CODEQL_VERSION_NEW_TRACING, getCodeQL } from "./codeql";
import { Config } from "./config-utils";
import { Logger } from "./logging";
import * as sharedEnv from "./shared-environment";
import {
bundleDb,
codeQlVersionAbove,
doesDirectoryExist,
getCachedCodeQlVersion,
getCodeQLDatabasePath,
getRequiredEnvParam,
GITHUB_DOTCOM_URL,
isGitHubGhesVersionBelow,
isHTTPError,
isInTestMode,
listFolder,
UserError,
} from "./util";
@@ -903,3 +914,147 @@ export async function uploadDebugArtifacts(
path.normalize(rootDir)
);
}
export async function uploadSarifDebugArtifact(
config: Config,
outputDir: string
) {
if (!doesDirectoryExist(outputDir)) {
return;
}
let toUpload: string[] = [];
for (const lang of config.languages) {
const sarifFile = path.resolve(outputDir, `${lang}.sarif`);
if (fs.existsSync(sarifFile)) {
toUpload = toUpload.concat(sarifFile);
}
}
await uploadDebugArtifacts(toUpload, outputDir, config.debugArtifactName);
}
export async function uploadFinalLogsDebugArtifact(config: Config) {
core.info("Debug mode is on. Printing CodeQL debug logs...");
for (const language of config.languages) {
const databaseDirectory = getCodeQLDatabasePath(config, language);
const logsDirectory = path.join(databaseDirectory, "log");
if (!doesDirectoryExist(logsDirectory)) {
core.info(`Directory ${logsDirectory} does not exist.`);
continue; // Skip this language database.
}
const walkLogFiles = (dir: string) => {
const entries = fs.readdirSync(dir, { withFileTypes: true });
if (entries.length === 0) {
core.info(`No debug logs found at directory ${logsDirectory}.`);
}
for (const entry of entries) {
if (entry.isFile()) {
core.startGroup(`CodeQL Debug Logs - ${language} - ${entry.name}`);
process.stdout.write(fs.readFileSync(path.resolve(dir, entry.name)));
core.endGroup();
} else if (entry.isDirectory()) {
walkLogFiles(path.resolve(dir, entry.name));
}
}
};
walkLogFiles(logsDirectory);
}
}
export async function uploadLogsDebugArtifact(config: Config) {
const codeql = await getCodeQL(config.codeQLCmd);
let toUpload: string[] = [];
for (const language of config.languages) {
const databaseDirectory = getCodeQLDatabasePath(config, language);
const logsDirectory = path.resolve(databaseDirectory, "log");
if (doesDirectoryExist(logsDirectory)) {
toUpload = toUpload.concat(listFolder(logsDirectory));
}
}
if (await codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING)) {
// Multilanguage tracing: there are additional logs in the root of the cluster
const multiLanguageTracingLogsDirectory = path.resolve(
config.dbLocation,
"log"
);
if (doesDirectoryExist(multiLanguageTracingLogsDirectory)) {
toUpload = toUpload.concat(listFolder(multiLanguageTracingLogsDirectory));
}
}
await uploadDebugArtifacts(
toUpload,
config.dbLocation,
config.debugArtifactName
);
// Before multi-language tracing, we wrote a compound-build-tracer.log in the temp dir
if (!(await codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING))) {
const compoundBuildTracerLogDirectory = path.resolve(
config.tempDir,
"compound-build-tracer.log"
);
if (doesDirectoryExist(compoundBuildTracerLogDirectory)) {
await uploadDebugArtifacts(
[compoundBuildTracerLogDirectory],
config.tempDir,
config.debugArtifactName
);
}
}
}
export async function uploadDatabaseBundleDebugArtifact(
config: Config,
logger: Logger
) {
for (const language of config.languages) {
if (!dbIsFinalized(config, language, logger)) {
// Zip up files and upload directly.
const databasePath = getCodeQLDatabasePath(config, language);
const databaseBundlePath = path.resolve(
config.dbLocation,
`${config.debugDatabaseName}-${language}-partial.zip`
);
core.info(
`${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...`
);
// See `bundleDb` for explanation behind deleting existing db bundle.
if (fs.existsSync(databaseBundlePath)) {
await del(databaseBundlePath, { force: true });
}
const zip = new AdmZip();
zip.addLocalFolder(databasePath);
zip.writeZip(databaseBundlePath);
await uploadDebugArtifacts(
[databaseBundlePath],
config.dbLocation,
config.debugArtifactName
);
continue;
}
try {
// Otherwise run `codeql database bundle` command.
const toUpload: string[] = [];
toUpload.push(
await bundleDb(
config,
language,
await getCodeQL(config.codeQLCmd),
`${config.debugDatabaseName}-${language}`
)
);
await uploadDebugArtifacts(
toUpload,
config.dbLocation,
config.debugArtifactName
);
} catch (error) {
core.info(
`Failed to upload database debug bundles for ${config.debugDatabaseName}-${language}: ${error}`
);
}
}
}

View File

@@ -1,33 +1,10 @@
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
import * as actionsUtil from "./actions-util";
import { Config, getConfig } from "./config-utils";
import { getActionsLogger } from "./logging";
import { doesDirectoryExist } from "./util";
async function uploadSarifDebugArtifact(config: Config, outputDir: string) {
if (!doesDirectoryExist(outputDir)) {
return;
}
let toUpload: string[] = [];
for (const lang of config.languages) {
const sarifFile = path.resolve(outputDir, `${lang}.sarif`);
if (fs.existsSync(sarifFile)) {
toUpload = toUpload.concat(sarifFile);
}
}
await actionsUtil.uploadDebugArtifacts(
toUpload,
outputDir,
config.debugArtifactName
);
}
async function run() {
async function run(uploadSarifDebugArtifact: Function) {
const logger = getActionsLogger();
let config: Config | undefined = undefined;
@@ -47,7 +24,7 @@ async function run() {
async function runWrapper() {
try {
await run();
await run(actionsUtil.uploadSarifDebugArtifact);
} catch (error) {
core.setFailed(`analyze action cleanup failed: ${error}`);
console.log(error);

View File

@@ -1,162 +1,14 @@
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
import AdmZip from "adm-zip";
import del from "del";
import * as actionsUtil from "./actions-util";
import { dbIsFinalized } from "./analyze";
import { CODEQL_VERSION_NEW_TRACING, getCodeQL } from "./codeql";
import { Config, getConfig } from "./config-utils";
import { getActionsLogger, Logger } from "./logging";
import {
bundleDb,
codeQlVersionAbove,
doesDirectoryExist,
getCodeQLDatabasePath,
} from "./util";
import { getActionsLogger } from "./logging";
function listFolder(dir: string): string[] {
const entries = fs.readdirSync(dir, { withFileTypes: true });
let files: string[] = [];
for (const entry of entries) {
if (entry.isFile()) {
files.push(path.resolve(dir, entry.name));
} else if (entry.isDirectory()) {
files = files.concat(listFolder(path.resolve(dir, entry.name)));
}
}
return files;
}
export async function uploadDatabaseBundleDebugArtifact(
config: Config,
logger: Logger
async function run(
uploadDatabaseBundleDebugArtifact: Function,
uploadLogsDebugArtifact: Function,
uploadFinalLogsDebugArtifact: Function
) {
for (const language of config.languages) {
if (!dbIsFinalized(config, language, logger)) {
// Zip up files and upload directly.
const databasePath = getCodeQLDatabasePath(config, language);
const databaseBundlePath = path.resolve(
config.dbLocation,
`${config.debugDatabaseName}-${language}-partial.zip`
);
core.info(
`${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...`
);
// See `bundleDb` for explanation behind deleting existing db bundle.
if (fs.existsSync(databaseBundlePath)) {
await del(databaseBundlePath, { force: true });
}
const zip = new AdmZip();
zip.addLocalFolder(databasePath);
zip.writeZip(databaseBundlePath);
await actionsUtil.uploadDebugArtifacts(
[databaseBundlePath],
config.dbLocation,
config.debugArtifactName
);
continue;
}
try {
// Otherwise run `codeql database bundle` command.
const toUpload: string[] = [];
toUpload.push(
await bundleDb(
config,
language,
await getCodeQL(config.codeQLCmd),
`${config.debugDatabaseName}-${language}`
)
);
await actionsUtil.uploadDebugArtifacts(
toUpload,
config.dbLocation,
config.debugArtifactName
);
} catch (error) {
core.info(
`Failed to upload database debug bundles for ${config.debugDatabaseName}-${language}: ${error}`
);
}
}
}
async function uploadLogsDebugArtifact(config: Config) {
const codeql = await getCodeQL(config.codeQLCmd);
let toUpload: string[] = [];
for (const language of config.languages) {
const databaseDirectory = getCodeQLDatabasePath(config, language);
const logsDirectory = path.resolve(databaseDirectory, "log");
if (doesDirectoryExist(logsDirectory)) {
toUpload = toUpload.concat(listFolder(logsDirectory));
}
}
if (await codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING)) {
// Multilanguage tracing: there are additional logs in the root of the cluster
const multiLanguageTracingLogsDirectory = path.resolve(
config.dbLocation,
"log"
);
if (doesDirectoryExist(multiLanguageTracingLogsDirectory)) {
toUpload = toUpload.concat(listFolder(multiLanguageTracingLogsDirectory));
}
}
await actionsUtil.uploadDebugArtifacts(
toUpload,
config.dbLocation,
config.debugArtifactName
);
// Before multi-language tracing, we wrote a compound-build-tracer.log in the temp dir
if (!(await codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING))) {
const compoundBuildTracerLogDirectory = path.resolve(
config.tempDir,
"compound-build-tracer.log"
);
if (doesDirectoryExist(compoundBuildTracerLogDirectory)) {
await actionsUtil.uploadDebugArtifacts(
[compoundBuildTracerLogDirectory],
config.tempDir,
config.debugArtifactName
);
}
}
}
async function uploadFinalLogsDebugArtifact(config: Config) {
core.info("Debug mode is on. Printing CodeQL debug logs...");
for (const language of config.languages) {
const databaseDirectory = getCodeQLDatabasePath(config, language);
const logsDirectory = path.join(databaseDirectory, "log");
if (!doesDirectoryExist(logsDirectory)) {
core.info(`Directory ${logsDirectory} does not exist.`);
continue; // Skip this language database.
}
const walkLogFiles = (dir: string) => {
const entries = fs.readdirSync(dir, { withFileTypes: true });
if (entries.length === 0) {
core.info(`No debug logs found at directory ${logsDirectory}.`);
}
for (const entry of entries) {
if (entry.isFile()) {
core.startGroup(`CodeQL Debug Logs - ${language} - ${entry.name}`);
process.stdout.write(fs.readFileSync(path.resolve(dir, entry.name)));
core.endGroup();
} else if (entry.isDirectory()) {
walkLogFiles(path.resolve(dir, entry.name));
}
}
};
walkLogFiles(logsDirectory);
}
}
async function run() {
const logger = getActionsLogger();
let config: Config | undefined = undefined;
@@ -177,7 +29,11 @@ async function run() {
async function runWrapper() {
try {
await run();
await run(
actionsUtil.uploadDatabaseBundleDebugArtifact,
actionsUtil.uploadLogsDebugArtifact,
actionsUtil.uploadFinalLogsDebugArtifact
);
} catch (error) {
core.setFailed(`init action cleanup failed: ${error}`);
console.log(error);

View File

@@ -768,3 +768,19 @@ export function doesDirectoryExist(dirPath: string): boolean {
return false;
}
}
/**
* Returns a list of files in a given directory.
*/
export function listFolder(dir: string): string[] {
const entries = fs.readdirSync(dir, { withFileTypes: true });
let files: string[] = [];
for (const entry of entries) {
if (entry.isFile()) {
files.push(path.resolve(dir, entry.name));
} else if (entry.isDirectory()) {
files = files.concat(listFolder(path.resolve(dir, entry.name)));
}
}
return files;
}