Upload databases from analyze action

This commit is contained in:
Robert 2021-06-10 16:09:58 +01:00
parent babcc1b793
commit 2a9a602a5e
6 changed files with 122 additions and 3 deletions

35
lib/analyze-action.js generated
View file

@ -12,8 +12,11 @@ const path = __importStar(require("path"));
const core = __importStar(require("@actions/core"));
const actionsUtil = __importStar(require("./actions-util"));
const analyze_1 = require("./analyze");
const api_client_1 = require("./api-client");
const codeql_1 = require("./codeql");
const config_utils_1 = require("./config-utils");
const logging_1 = require("./logging");
const repository_1 = require("./repository");
const upload_lib = __importStar(require("./upload-lib"));
const util = __importStar(require("./util"));
// eslint-disable-next-line import/no-commonjs
@ -30,6 +33,36 @@ async function sendStatusReport(startedAt, stats, error) {
};
await actionsUtil.sendStatusReport(statusReport);
}
async function uploadDatabases(repositoryNwo, config, apiDetails, logger) {
const client = api_client_1.getApiClient(apiDetails);
const optInResponse = await client.request("GET /repos/:owner/:repo/code-scanning/databases", {
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
});
if (optInResponse.status !== 204) {
// Repository is not opted in to database uploads.
logger.debug("Repository is not opted in to database uploads. Skipping upload.");
return;
}
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
for (const language of config.languages) {
// Bundle the database up into a single zip file
const databasePath = util.getCodeQLDatabasePath(config, language);
const databaseBundlePath = `${databasePath}.zip`;
await codeql.databaseBundle(databasePath, databaseBundlePath);
// Upload the database bundle
const payload = fs.readFileSync(databaseBundlePath);
const uploadResponse = await client.request(`PUT /repos/:owner/:repo/code-scanning/databases/${language}`, {
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
});
if (uploadResponse.status !== 201) {
// Log a warning but don't fail the workflow
logger.warning(`Failed to upload database for ${language}. ${uploadResponse.data}`);
}
}
}
async function run() {
const startedAt = new Date();
let stats = undefined;
@ -66,6 +99,8 @@ async function run() {
logger.info("Not uploading results");
stats = { ...queriesStats };
}
const repositoryNwo = repository_1.parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY"));
await uploadDatabases(repositoryNwo, config, apiDetails, logger);
}
catch (error) {
core.setFailed(error.message);

File diff suppressed because one or more lines are too long

10
lib/codeql.js generated
View file

@ -286,6 +286,7 @@ function setCodeQL(partialCodeql) {
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
resolveQueries: resolveFunction(partialCodeql, "resolveQueries"),
databaseCleanup: resolveFunction(partialCodeql, "databaseCleanup"),
databaseBundle: resolveFunction(partialCodeql, "databaseBundle"),
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
databaseInterpretResults: resolveFunction(partialCodeql, "databaseInterpretResults"),
};
@ -520,6 +521,15 @@ function getCodeQLForCmd(cmd) {
];
await new toolrunner.ToolRunner(cmd, args).exec();
},
async databaseBundle(databasePath, outputFilePath) {
const args = [
"database",
"cleanup",
databasePath,
`--output=${outputFilePath}`,
];
await new toolrunner.ToolRunner(cmd, args).exec();
},
};
}
/**

File diff suppressed because one or more lines are too long

View file

@ -10,8 +10,11 @@ import {
QueriesStatusReport,
runCleanup,
} from "./analyze";
import { getApiClient, GitHubApiDetails } from "./api-client";
import { getCodeQL } from "./codeql";
import { Config, getConfig } from "./config-utils";
import { getActionsLogger } from "./logging";
import { getActionsLogger, Logger } from "./logging";
import { parseRepositoryNwo, RepositoryNwo } from "./repository";
import * as upload_lib from "./upload-lib";
import * as util from "./util";
@ -49,6 +52,55 @@ async function sendStatusReport(
await actionsUtil.sendStatusReport(statusReport);
}
async function uploadDatabases(
repositoryNwo: RepositoryNwo,
config: Config,
apiDetails: GitHubApiDetails,
logger: Logger
): Promise<void> {
const client = getApiClient(apiDetails);
const optInResponse = await client.request(
"GET /repos/:owner/:repo/code-scanning/databases",
{
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
}
);
if (optInResponse.status !== 204) {
// Repository is not opted in to database uploads.
logger.debug(
"Repository is not opted in to database uploads. Skipping upload."
);
return;
}
const codeql = getCodeQL(config.codeQLCmd);
for (const language of config.languages) {
// Bundle the database up into a single zip file
const databasePath = util.getCodeQLDatabasePath(config, language);
const databaseBundlePath = `${databasePath}.zip`;
await codeql.databaseBundle(databasePath, databaseBundlePath);
// Upload the database bundle
const payload = fs.readFileSync(databaseBundlePath);
const uploadResponse = await client.request(
`PUT /repos/:owner/:repo/code-scanning/databases/${language}`,
{
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
}
);
if (uploadResponse.status !== 201) {
// Log a warning but don't fail the workflow
logger.warning(
`Failed to upload database for ${language}. ${uploadResponse.data}`
);
}
}
}
async function run() {
const startedAt = new Date();
let stats: AnalysisStatusReport | undefined = undefined;
@ -116,6 +168,11 @@ async function run() {
logger.info("Not uploading results");
stats = { ...queriesStats };
}
const repositoryNwo = parseRepositoryNwo(
util.getRequiredEnvParam("GITHUB_REPOSITORY")
);
await uploadDatabases(repositoryNwo, config, apiDetails, logger);
} catch (error) {
core.setFailed(error.message);
console.log(error);

View file

@ -92,6 +92,10 @@ export interface CodeQL {
* Run 'codeql database cleanup'.
*/
databaseCleanup(databasePath: string, cleanupLevel: string): Promise<void>;
/**
* Run 'codeql database bundle'.
*/
databaseBundle(databasePath: string, outputFilePath: string): Promise<void>;
/**
* Run 'codeql database run-queries'.
*/
@ -493,6 +497,7 @@ export function setCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
resolveQueries: resolveFunction(partialCodeql, "resolveQueries"),
databaseCleanup: resolveFunction(partialCodeql, "databaseCleanup"),
databaseBundle: resolveFunction(partialCodeql, "databaseBundle"),
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
databaseInterpretResults: resolveFunction(
partialCodeql,
@ -791,6 +796,18 @@ function getCodeQLForCmd(cmd: string): CodeQL {
];
await new toolrunner.ToolRunner(cmd, args).exec();
},
async databaseBundle(
databasePath: string,
outputFilePath: string
): Promise<void> {
const args = [
"database",
"cleanup",
databasePath,
`--output=${outputFilePath}`,
];
await new toolrunner.ToolRunner(cmd, args).exec();
},
};
}