Skip to content

Commit

Permalink
Showing 12 changed files with 186 additions and 66 deletions.
54 changes: 53 additions & 1 deletion .github/workflows/pr-checks.yml
@@ -121,7 +121,6 @@ jobs:
languages: javascript
# TODO: this can be removed when cli v2.5.6 is released and available in the tool cache
tools: https://github.com/dsp-testing/aeisenberg-codeql-action-packaging/releases/download/codeql-bundle-20210615/codeql-bundle-linux64.tar.gz

- name: Build code
shell: bash
run: ./build.sh
@@ -234,6 +233,59 @@ jobs:
exit 1
fi
# Tests a split workflow where database construction and query execution happen in different steps
test-split-workflow:
needs: [check-js, check-node-modules]
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Move codeql-action
shell: bash
run: |
mkdir ../action
mv * .github ../action/
mv ../action/tests/multi-language-repo/{*,.github} .
mv ../action/.github/workflows .github
- uses: ./../action/init
with:
config-file: ".github/codeql/codeql-config-packaging3.yml"
packs: +dsp-testing/codeql-pack1@0.0.4
languages: javascript
tools: latest
- name: Build code
shell: bash
run: ./build.sh
- uses: ./../action/analyze
with:
skip-queries: true
output: "${{ runner.temp }}/results"
env:
TEST_MODE: true
- name: Assert No Results
run: |
if [ "$(ls -A $RUNNER_TEMP/results)" ]; then
echo "Expected results directory to be empty after skipping query execution!"
exit 1
fi
- uses: ./../action/analyze
with:
output: "${{ runner.temp }}/results"
env:
TEST_MODE: true
- name: Assert Results
run: |
cd "$RUNNER_TEMP/results"
# We should have 3 hits from these rules
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
echo "Found matching rules '$RULES'"
if [ "$RULES" != "$EXPECTED_RULES" ]; then
echo "Did not match expected rules '$EXPECTED_RULES'."
exit 1
fi
# Identify the CodeQL tool versions to integration test against.
check-codeql-versions:
2 changes: 1 addition & 1 deletion CHANGELOG.md
@@ -2,7 +2,7 @@

## [UNRELEASED]

No user facing changes.
- The `analyze` step of the Action now supports a `skip-queries` option to merely build the CodeQL database without analyzing. This functionality is not present in the runner. Additionally, the step will no longer fail if it encounters a finalized database, and will instead continue with query execution. [#602](https://github.com/github/codeql-action/pull/602)

## 1.0.4 - 28 Jun 2021

4 changes: 4 additions & 0 deletions analyze/action.yml
@@ -24,6 +24,10 @@ inputs:
description: Specify whether or not to add code snippets to the output sarif file.
required: false
default: "false"
skip-queries:
description: If this option is set, the CodeQL database will be built but no queries will be run on it. Thus, no results will be produced.
required: false
default: "false"
threads:
description: The number of threads to be used by CodeQL.
required: false
32 changes: 23 additions & 9 deletions lib/analyze-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/analyze-action.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 24 additions & 8 deletions lib/analyze.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/analyze.js.map

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion lib/runner.js
2 changes: 1 addition & 1 deletion lib/runner.js.map

Large diffs are not rendered by default.

48 changes: 32 additions & 16 deletions src/analyze-action.ts
@@ -5,16 +5,18 @@ import * as core from "@actions/core";

import * as actionsUtil from "./actions-util";
import {
runAnalyze,
CodeQLAnalysisError,
QueriesStatusReport,
runCleanup,
runQueries,
runFinalize,
} from "./analyze";
import { Config, getConfig } from "./config-utils";
import { uploadDatabases } from "./database-upload";
import { getActionsLogger } from "./logging";
import { parseRepositoryNwo } from "./repository";
import * as upload_lib from "./upload-lib";
import { UploadStatusReport } from "./upload-lib";
import * as util from "./util";

// eslint-disable-next-line import/no-commonjs
@@ -53,7 +55,8 @@ async function sendStatusReport(

async function run() {
const startedAt = new Date();
let stats: AnalysisStatusReport | undefined = undefined;
let uploadStats: UploadStatusReport | undefined = undefined;
let runStats: QueriesStatusReport | undefined = undefined;
let config: Config | undefined = undefined;
util.initializeEnvironment(util.Mode.actions, pkg.version);

@@ -82,15 +85,22 @@ async function run() {
url: util.getRequiredEnvParam("GITHUB_SERVER_URL"),
};
const outputDir = actionsUtil.getRequiredInput("output");
const queriesStats = await runAnalyze(
outputDir,
util.getMemoryFlag(actionsUtil.getOptionalInput("ram")),
util.getAddSnippetsFlag(actionsUtil.getRequiredInput("add-snippets")),
util.getThreadsFlag(actionsUtil.getOptionalInput("threads"), logger),
actionsUtil.getOptionalInput("category"),
config,
const threads = util.getThreadsFlag(
actionsUtil.getOptionalInput("threads"),
logger
);
await runFinalize(outputDir, threads, config, logger);
if (actionsUtil.getRequiredInput("skip-queries") !== "true") {
runStats = await runQueries(
outputDir,
util.getMemoryFlag(actionsUtil.getOptionalInput("ram")),
util.getAddSnippetsFlag(actionsUtil.getRequiredInput("add-snippets")),
threads,
actionsUtil.getOptionalInput("category"),
config,
logger
);
}

if (actionsUtil.getOptionalInput("cleanup-level") !== "none") {
await runCleanup(
@@ -106,17 +116,15 @@ async function run() {
}
core.setOutput("db-locations", dbLocations);

if (actionsUtil.getRequiredInput("upload") === "true") {
const uploadStats = await upload_lib.uploadFromActions(
if (runStats && actionsUtil.getRequiredInput("upload") === "true") {
uploadStats = await upload_lib.uploadFromActions(
outputDir,
config.gitHubVersion,
apiDetails,
logger
);
stats = { ...queriesStats, ...uploadStats };
} else {
logger.info("Not uploading results");
stats = { ...queriesStats };
}

const repositoryNwo = parseRepositoryNwo(
@@ -128,10 +136,12 @@ async function run() {
console.log(error);

if (error instanceof CodeQLAnalysisError) {
stats = { ...error.queriesStatusReport };
const stats = { ...error.queriesStatusReport };
await sendStatusReport(startedAt, stats, error);
} else {
await sendStatusReport(startedAt, undefined, error);
}

await sendStatusReport(startedAt, stats, error);
return;
} finally {
if (core.isDebug() && config !== undefined) {
@@ -161,7 +171,13 @@ async function run() {
}
}

await sendStatusReport(startedAt, stats);
if (runStats && uploadStats) {
await sendStatusReport(startedAt, { ...runStats, ...uploadStats });
} else if (runStats) {
await sendStatusReport(startedAt, { ...runStats });
} else {
await sendStatusReport(startedAt, undefined);
}
}

async function runWrapper() {
62 changes: 38 additions & 24 deletions src/analyze.ts
@@ -2,6 +2,7 @@ import * as fs from "fs";
import * as path from "path";

import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as yaml from "js-yaml";

import * as analysisPaths from "./analysis-paths";
import { getCodeQL } from "./codeql";
@@ -117,7 +118,10 @@ async function createdDBForScannedLanguages(

const codeql = getCodeQL(config.codeQLCmd);
for (const language of config.languages) {
if (isScannedLanguage(language)) {
if (
isScannedLanguage(language) &&
!dbIsFinalized(config, language, logger)
) {
logger.startGroup(`Extracting ${language}`);

if (language === Language.python) {
@@ -133,6 +137,25 @@ async function createdDBForScannedLanguages(
}
}

function dbIsFinalized(
config: configUtils.Config,
language: Language,
logger: Logger
) {
const dbPath = util.getCodeQLDatabasePath(config, language);
try {
const dbInfo = yaml.load(
fs.readFileSync(path.resolve(dbPath, "codeql-database.yml"), "utf8")
);
return !("inProgress" in dbInfo);
} catch (e) {
logger.warning(
`Could not check whether database for ${language} was finalized. Assuming it is not.`
);
return false;
}
}

async function finalizeDatabaseCreation(
config: configUtils.Config,
threadsFlag: string,
@@ -142,12 +165,18 @@ async function finalizeDatabaseCreation(

const codeql = getCodeQL(config.codeQLCmd);
for (const language of config.languages) {
logger.startGroup(`Finalizing ${language}`);
await codeql.finalizeDatabase(
util.getCodeQLDatabasePath(config, language),
threadsFlag
);
logger.endGroup();
if (dbIsFinalized(config, language, logger)) {
logger.info(
`There is already a finalized database for ${language} at the location where the CodeQL Action places databases, so we did not create one.`
);
} else {
logger.startGroup(`Finalizing ${language}`);
await codeql.finalizeDatabase(
util.getCodeQLDatabasePath(config, language),
threadsFlag
);
logger.endGroup();
}
}
}

@@ -349,33 +378,18 @@ function packWithVersionToQuerySuiteEntry(
return text;
}

export async function runAnalyze(
export async function runFinalize(
outputDir: string,
memoryFlag: string,
addSnippetsFlag: string,
threadsFlag: string,
automationDetailsId: string | undefined,
config: configUtils.Config,
logger: Logger
): Promise<QueriesStatusReport> {
) {
// Delete the tracer config env var to avoid tracing ourselves
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];

fs.mkdirSync(outputDir, { recursive: true });

await finalizeDatabaseCreation(config, threadsFlag, logger);

const queriesStats = await runQueries(
outputDir,
memoryFlag,
addSnippetsFlag,
threadsFlag,
automationDetailsId,
config,
logger
);

return { ...queriesStats };
}

export async function runCleanup(
8 changes: 5 additions & 3 deletions src/runner.ts
@@ -4,7 +4,7 @@ import * as path from "path";

import { Command } from "commander";

import { runAnalyze } from "./analyze";
import { runFinalize, runQueries } from "./analyze";
import { determineAutobuildLanguage, runAutobuild } from "./autobuild";
import { CodeQL, getCodeQL } from "./codeql";
import { Config, getConfig } from "./config-utils";
@@ -431,11 +431,13 @@ program

const outputDir =
cmd.outputDir || path.join(config.tempDir, "codeql-sarif");
await runAnalyze(
const threads = getThreadsFlag(cmd.threads, logger);
await runFinalize(outputDir, threads, config, logger);
await runQueries(
outputDir,
getMemoryFlag(cmd.ram),
getAddSnippetsFlag(cmd.addSnippets),
getThreadsFlag(cmd.threads, logger),
threads,
cmd.category,
config,
logger

0 comments on commit ef852c0

Please sign in to comment.