Merge branch 'main' into aeisenberg/fix-config-files

This commit is contained in:
Andrew Eisenberg 2022-07-13 13:27:04 -07:00
commit 01d16b1e01
71 changed files with 423 additions and 1076 deletions

View file

@ -57,13 +57,6 @@ export function getTemporaryDirectory(): string {
: getRequiredEnvParam("RUNNER_TEMP");
}
export function getToolCacheDirectory(): string {
const value = process.env["CODEQL_ACTION_TOOL_CACHE"];
return value !== undefined && value !== ""
? value
: getRequiredEnvParam("RUNNER_TOOL_CACHE");
}
/**
* Gets the SHA of the commit that is currently checked out.
*/

View file

@ -17,7 +17,6 @@ test("emptyPaths", async (t) => {
paths: [],
originalUserInput: {},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM } as util.GitHubVersion,
dbLocation: path.resolve(tmpDir, "codeql_databases"),
@ -47,7 +46,6 @@ test("nonEmptyPaths", async (t) => {
pathsIgnore: ["path4", "path5", "path6/**"],
originalUserInput: {},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM } as util.GitHubVersion,
dbLocation: path.resolve(tmpDir, "codeql_databases"),
@ -72,32 +70,29 @@ test("nonEmptyPaths", async (t) => {
});
test("exclude temp dir", async (t) => {
return await util.withTmpDir(async (toolCacheDir) => {
const tempDir = path.join(process.cwd(), "codeql-runner-temp");
const config = {
languages: [],
queries: {},
pathsIgnore: [],
paths: [],
originalUserInput: {},
tempDir,
toolCacheDir,
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM } as util.GitHubVersion,
dbLocation: path.resolve(tempDir, "codeql_databases"),
packs: {},
debugMode: false,
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
augmentationProperties: {
injectedMlQueries: false,
packsInputCombines: false,
queriesInputCombines: false,
},
};
analysisPaths.includeAndExcludeAnalysisPaths(config);
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
t.is(process.env["LGTM_INDEX_EXCLUDE"], "codeql-runner-temp");
t.is(process.env["LGTM_INDEX_FILTERS"], undefined);
});
const tempDir = path.join(process.cwd(), "codeql-runner-temp");
const config = {
languages: [],
queries: {},
pathsIgnore: [],
paths: [],
originalUserInput: {},
tempDir,
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM } as util.GitHubVersion,
dbLocation: path.resolve(tempDir, "codeql_databases"),
packs: {},
debugMode: false,
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
augmentationProperties: {
injectedMlQueries: false,
packsInputCombines: false,
queriesInputCombines: false,
},
};
analysisPaths.includeAndExcludeAnalysisPaths(config);
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
t.is(process.env["LGTM_INDEX_EXCLUDE"], "codeql-runner-temp");
t.is(process.env["LGTM_INDEX_FILTERS"], undefined);
});

View file

@ -54,17 +54,13 @@ export function includeAndExcludeAnalysisPaths(config: configUtils.Config) {
}
// If the temporary or tools directory is in the working directory ignore that too.
const tempRelativeToWorking = path.relative(process.cwd(), config.tempDir);
const toolsRelativeToWorking = path.relative(
process.cwd(),
config.toolCacheDir
);
let pathsIgnore = config.pathsIgnore;
if (!tempRelativeToWorking.startsWith("..")) {
if (
!tempRelativeToWorking.startsWith("..") &&
!path.isAbsolute(tempRelativeToWorking)
) {
pathsIgnore = pathsIgnore.concat(tempRelativeToWorking);
}
if (!toolsRelativeToWorking.startsWith("..")) {
pathsIgnore = pathsIgnore.concat(toolsRelativeToWorking);
}
if (pathsIgnore.length !== 0) {
process.env["LGTM_INDEX_EXCLUDE"] = buildIncludeExcludeEnvVar(pathsIgnore);
}

View file

@ -151,17 +151,19 @@ async function run() {
if (config.debugMode) {
// Upload the logs as an Actions artifact for debugging
const toUpload: string[] = [];
let toUpload: string[] = [];
for (const language of config.languages) {
toUpload.push(
...listFolder(
toUpload = toUpload.concat(
listFolder(
path.resolve(util.getCodeQLDatabasePath(config, language), "log")
)
);
}
if (await codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING)) {
// Multilanguage tracing: there are additional logs in the root of the cluster
toUpload.push(...listFolder(path.resolve(config.dbLocation, "log")));
toUpload = toUpload.concat(
listFolder(path.resolve(config.dbLocation, "log"))
);
}
await uploadDebugArtifacts(
toUpload,
@ -236,7 +238,7 @@ async function run() {
return;
} finally {
if (config !== undefined && config.debugMode) {
if (config?.debugMode) {
try {
// Upload the database bundles as an Actions artifact for debugging
const toUpload: string[] = [];
@ -260,7 +262,7 @@ async function run() {
}
}
if (core.isDebug() && config !== undefined) {
if (config?.debugMode) {
core.info("Debug mode is on. Printing CodeQL debug logs...");
for (const language of config.languages) {
const databaseDirectory = util.getCodeQLDatabasePath(config, language);
@ -319,12 +321,12 @@ async function uploadDebugArtifacts(
function listFolder(dir: string): string[] {
const entries = fs.readdirSync(dir, { withFileTypes: true });
const files: string[] = [];
let files: string[] = [];
for (const entry of entries) {
if (entry.isFile()) {
files.push(path.resolve(dir, entry.name));
} else if (entry.isDirectory()) {
files.push(...listFolder(path.resolve(dir, entry.name)));
files = files.concat(listFolder(path.resolve(dir, entry.name)));
}
}
return files;

View file

@ -103,7 +103,6 @@ test("status report fields and search path setting", async (t) => {
paths: [],
originalUserInput: {},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: "",
gitHubVersion: {
type: util.GitHubVariant.DOTCOM,
@ -263,7 +262,6 @@ const stubConfig: Config = {
paths: [],
originalUserInput: {},
tempDir: "",
toolCacheDir: "",
codeQLCmd: "",
gitHubVersion: {
type: util.GitHubVariant.DOTCOM,

View file

@ -209,11 +209,9 @@ export async function runQueries(
{}
);
const cliCanCountBaseline = await cliCanCountLoC();
const debugMode =
process.env["INTERNAL_CODEQL_ACTION_DEBUG_LOC"] ||
process.env["ACTIONS_RUNNER_DEBUG"] ||
process.env["ACTIONS_STEP_DEBUG"];
if (!cliCanCountBaseline || debugMode) {
const countLocDebugMode =
process.env["INTERNAL_CODEQL_ACTION_DEBUG_LOC"] || config.debugMode;
if (!cliCanCountBaseline || countLocDebugMode) {
// count the number of lines in the background
locPromise = countLoc(
path.resolve(),
@ -263,7 +261,8 @@ export async function runQueries(
const analysisSummary = await runInterpretResults(
language,
undefined,
sarifFile
sarifFile,
config.debugMode
);
statusReport[`interpret_results_${language}_duration_ms`] =
new Date().getTime() - startTimeInterpretResults;
@ -337,7 +336,8 @@ export async function runQueries(
const analysisSummary = await runInterpretResults(
language,
querySuitePaths,
sarifFile
sarifFile,
config.debugMode
);
if (!cliCanCountBaseline) {
await injectLinesOfCode(sarifFile, language, locPromise);
@ -347,7 +347,7 @@ export async function runQueries(
logger.endGroup();
logger.info(analysisSummary);
}
if (!cliCanCountBaseline || debugMode) {
if (!cliCanCountBaseline || countLocDebugMode) {
printLinesOfCodeSummary(logger, language, await locPromise);
}
if (cliCanCountBaseline) {
@ -371,7 +371,8 @@ export async function runQueries(
async function runInterpretResults(
language: Language,
queries: string[] | undefined,
sarifFile: string
sarifFile: string,
enableDebugLogging: boolean
): Promise<string> {
const databasePath = util.getCodeQLDatabasePath(config, language);
return await codeql.databaseInterpretResults(
@ -380,6 +381,7 @@ export async function runQueries(
sarifFile,
addSnippetsFlag,
threadsFlag,
enableDebugLogging ? "-vv" : "-v",
automationDetailsId
);
}
@ -464,15 +466,6 @@ export async function runFinalize(
logger: Logger,
featureFlags: FeatureFlags
) {
const codeql = await getCodeQL(config.codeQLCmd);
if (await util.codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING)) {
// Delete variables as specified by the end-tracing script
await endTracingForCluster(config);
} else {
// Delete the tracer config env var to avoid tracing ourselves
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
}
try {
await del(outputDir, { force: true });
} catch (error: any) {
@ -489,6 +482,20 @@ export async function runFinalize(
logger,
featureFlags
);
const codeql = await getCodeQL(config.codeQLCmd);
// WARNING: This does not _really_ end tracing, as the tracer will restore its
// critical environment variables and it'll still be active for all processes
// launched from this build step.
// However, it will stop tracing for all steps past the codeql-action/analyze
// step.
if (await util.codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING)) {
// Delete variables as specified by the end-tracing script
await endTracingForCluster(config);
} else {
// Delete the tracer config env var to avoid tracing ourselves
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
}
}
export async function runCleanup(

View file

@ -43,7 +43,6 @@ test.beforeEach(() => {
paths: [],
originalUserInput: {},
tempDir: "",
toolCacheDir: "",
codeQLCmd: "",
gitHubVersion: {
type: util.GitHubVariant.DOTCOM,
@ -81,7 +80,6 @@ test("download codeql bundle cache", async (t) => {
`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`,
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -111,7 +109,6 @@ test("download codeql bundle cache explicitly requested with pinned different ve
"https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz",
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -130,7 +127,6 @@ test("download codeql bundle cache explicitly requested with pinned different ve
"https://example.com/download/codeql-bundle-20200610/codeql-bundle.tar.gz",
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -155,7 +151,6 @@ test("don't download codeql bundle cache with pinned different version cached",
"https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz",
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -167,7 +162,6 @@ test("don't download codeql bundle cache with pinned different version cached",
undefined,
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -194,7 +188,6 @@ test("download codeql bundle cache with different version cached (not pinned)",
"https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz",
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -221,7 +214,6 @@ test("download codeql bundle cache with different version cached (not pinned)",
undefined,
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -248,7 +240,6 @@ test('download codeql bundle cache with pinned different version cached if "late
"https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz",
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -276,7 +267,6 @@ test('download codeql bundle cache with pinned different version cached if "late
"latest",
sampleApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.DOTCOM,
getRunnerLogger(true),
false
@ -331,7 +321,6 @@ test("download codeql bundle from github ae endpoint", async (t) => {
undefined,
sampleGHAEApiDetails,
tmpDir,
tmpDir,
util.GitHubVariant.GHAE,
getRunnerLogger(true),
false
@ -439,7 +428,7 @@ test("databaseInterpretResults() does not set --sarif-add-query-help for 2.7.0",
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeqlObject, "getVersion").resolves("2.7.0");
await codeqlObject.databaseInterpretResults("", [], "", "", "", "");
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "");
t.false(
runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"),
"--sarif-add-query-help should be absent, but it is present"
@ -450,7 +439,7 @@ test("databaseInterpretResults() sets --sarif-add-query-help for 2.7.1", async (
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeqlObject, "getVersion").resolves("2.7.1");
await codeqlObject.databaseInterpretResults("", [], "", "", "", "");
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "");
t.true(
runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"),
"--sarif-add-query-help should be present, but it is absent"
@ -658,7 +647,7 @@ test(
},
{},
{
packs: ["codeql/javascript-experimental-atm-queries@~0.1.0"],
packs: ["codeql/javascript-experimental-atm-queries@~0.3.0"],
}
);
@ -679,7 +668,7 @@ test(
packs: {
javascript: [
"codeql/something-else",
"codeql/javascript-experimental-atm-queries@~0.1.0",
"codeql/javascript-experimental-atm-queries@~0.3.0",
],
},
}
@ -701,7 +690,7 @@ test(
{
packs: {
cpp: ["codeql/something-else"],
javascript: ["codeql/javascript-experimental-atm-queries@~0.1.0"],
javascript: ["codeql/javascript-experimental-atm-queries@~0.3.0"],
},
}
);
@ -782,7 +771,7 @@ test(
},
},
{
packs: ["xxx", "yyy", "codeql/javascript-experimental-atm-queries@~0.1.0"],
packs: ["xxx", "yyy", "codeql/javascript-experimental-atm-queries@~0.3.0"],
}
);

View file

@ -3,10 +3,12 @@ import { OutgoingHttpHeaders } from "http";
import * as path from "path";
import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as toolcache from "@actions/tool-cache";
import { default as deepEqual } from "fast-deep-equal";
import * as yaml from "js-yaml";
import { default as queryString } from "query-string";
import * as semver from "semver";
import { v4 as uuidV4 } from "uuid";
import { isRunningLocalAction, getRelativeScriptPath } from "./actions-util";
import * as api from "./api-client";
@ -16,7 +18,6 @@ import { errorMatchers } from "./error-matcher";
import { FeatureFlags, FeatureFlag } from "./feature-flags";
import { isTracedLanguage, Language } from "./languages";
import { Logger } from "./logging";
import * as toolcache from "./toolcache";
import { toolrunnerErrorCatcher } from "./toolrunner-error-catcher";
import * as util from "./util";
import { isGoodVersion } from "./util";
@ -157,6 +158,7 @@ export interface CodeQL {
sarifFile: string,
addSnippetsFlag: string,
threadsFlag: string,
verbosityFlag: string | undefined,
automationDetailsId: string | undefined
): Promise<string>;
/**
@ -387,7 +389,6 @@ async function getCodeQLBundleDownloadURL(
* @param codeqlURL
* @param apiDetails
* @param tempDir
* @param toolCacheDir
* @param variant
* @param logger
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
@ -398,7 +399,6 @@ export async function setupCodeQL(
codeqlURL: string | undefined,
apiDetails: api.GitHubApiDetails,
tempDir: string,
toolCacheDir: string,
variant: util.GitHubVariant,
logger: Logger,
checkVersion: boolean
@ -413,7 +413,7 @@ export async function setupCodeQL(
let codeqlFolder: string;
let codeqlURLVersion: string;
if (codeqlURL && !codeqlURL.startsWith("http")) {
codeqlFolder = await toolcache.extractTar(codeqlURL, tempDir, logger);
codeqlFolder = await toolcache.extractTar(codeqlURL);
codeqlURLVersion = "local";
} else {
codeqlURLVersion = getCodeQLURLVersion(
@ -422,29 +422,15 @@ export async function setupCodeQL(
const codeqlURLSemVer = convertToSemVer(codeqlURLVersion, logger);
// If we find the specified version, we always use that.
codeqlFolder = toolcache.find(
"CodeQL",
codeqlURLSemVer,
toolCacheDir,
logger
);
codeqlFolder = toolcache.find("CodeQL", codeqlURLSemVer);
// If we don't find the requested version, in some cases we may allow a
// different version to save download time if the version hasn't been
// specified explicitly (in which case we always honor it).
if (!codeqlFolder && !codeqlURL && !forceLatest) {
const codeqlVersions = toolcache.findAllVersions(
"CodeQL",
toolCacheDir,
logger
);
const codeqlVersions = toolcache.findAllVersions("CodeQL");
if (codeqlVersions.length === 1 && isGoodVersion(codeqlVersions[0])) {
const tmpCodeqlFolder = toolcache.find(
"CodeQL",
codeqlVersions[0],
toolCacheDir,
logger
);
const tmpCodeqlFolder = toolcache.find("CodeQL", codeqlVersions[0]);
if (fs.existsSync(path.join(tmpCodeqlFolder, "pinned-version"))) {
logger.debug(
`CodeQL in cache overriding the default ${CODEQL_BUNDLE_VERSION}`
@ -486,24 +472,25 @@ export async function setupCodeQL(
logger.info(
`Downloading CodeQL tools from ${codeqlURL}. This may take a while.`
);
const dest = path.join(tempDir, uuidV4());
const finalHeaders = Object.assign(
{ "User-Agent": "CodeQL Action" },
headers
);
const codeqlPath = await toolcache.downloadTool(
codeqlURL,
tempDir,
headers
dest,
undefined,
finalHeaders
);
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
const codeqlExtracted = await toolcache.extractTar(
codeqlPath,
tempDir,
logger
);
const codeqlExtracted = await toolcache.extractTar(codeqlPath);
codeqlFolder = await toolcache.cacheDir(
codeqlExtracted,
"CodeQL",
codeqlURLSemVer,
toolCacheDir,
logger
codeqlURLSemVer
);
}
}
@ -952,6 +939,7 @@ async function getCodeQLForCmd(
sarifFile: string,
addSnippetsFlag: string,
threadsFlag: string,
verbosityFlag: string,
automationDetailsId: string | undefined
): Promise<string> {
const codeqlArgs = [
@ -959,7 +947,7 @@ async function getCodeQLForCmd(
"interpret-results",
threadsFlag,
"--format=sarif-latest",
"-v",
verbosityFlag,
`--output=${sarifFile}`,
addSnippetsFlag,
...getExtraOptionsFromEnv(["database", "interpret-results"]),

View file

@ -90,7 +90,6 @@ test("load empty config", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -111,7 +110,6 @@ test("load empty config", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -157,7 +155,6 @@ test("loading config saves config", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -194,7 +191,6 @@ test("load input outside of workspace", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
getCachedCodeQL(),
tmpDir,
gitHubVersion,
@ -233,7 +229,6 @@ test("load non-local input with invalid repo syntax", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
getCachedCodeQL(),
tmpDir,
gitHubVersion,
@ -273,7 +268,6 @@ test("load non-existent input", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
getCachedCodeQL(),
tmpDir,
gitHubVersion,
@ -350,7 +344,6 @@ test("load non-empty input", async (t) => {
paths: ["c/d"],
},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: codeQL.getPath(),
gitHubVersion,
dbLocation: path.resolve(tmpDir, "codeql_databases"),
@ -381,7 +374,6 @@ test("load non-empty input", async (t) => {
"my-db",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -448,7 +440,6 @@ test("Default queries are used", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -523,7 +514,6 @@ test("Queries can be specified in config file", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -537,16 +527,21 @@ test("Queries can be specified in config file", async (t) => {
// and once for `./foo` from the config file.
t.deepEqual(resolveQueriesArgs.length, 2);
t.deepEqual(resolveQueriesArgs[1].queries.length, 1);
t.regex(resolveQueriesArgs[1].queries[0], /.*\/foo$/);
t.true(resolveQueriesArgs[1].queries[0].endsWith(`${path.sep}foo`));
// Now check that the end result contains the default queries and the query from config
t.deepEqual(config.queries["javascript"].builtin.length, 1);
t.deepEqual(config.queries["javascript"].custom.length, 1);
t.regex(
config.queries["javascript"].builtin[0],
/javascript-code-scanning.qls$/
t.true(
config.queries["javascript"].builtin[0].endsWith(
"javascript-code-scanning.qls"
)
);
t.true(
config.queries["javascript"].custom[0].queries[0].endsWith(
`${path.sep}foo`
)
);
t.regex(config.queries["javascript"].custom[0].queries[0], /.*\/foo$/);
});
});
@ -592,7 +587,6 @@ test("Queries from config file can be overridden in workflow file", async (t) =>
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -606,16 +600,21 @@ test("Queries from config file can be overridden in workflow file", async (t) =>
// but won't be called for './foo' from the config file.
t.deepEqual(resolveQueriesArgs.length, 2);
t.deepEqual(resolveQueriesArgs[1].queries.length, 1);
t.regex(resolveQueriesArgs[1].queries[0], /.*\/override$/);
t.true(resolveQueriesArgs[1].queries[0].endsWith(`${path.sep}override`));
// Now check that the end result contains only the default queries and the override query
t.deepEqual(config.queries["javascript"].builtin.length, 1);
t.deepEqual(config.queries["javascript"].custom.length, 1);
t.regex(
config.queries["javascript"].builtin[0],
/javascript-code-scanning.qls$/
t.true(
config.queries["javascript"].builtin[0].endsWith(
"javascript-code-scanning.qls"
)
);
t.true(
config.queries["javascript"].custom[0].queries[0].endsWith(
`${path.sep}override`
)
);
t.regex(config.queries["javascript"].custom[0].queries[0], /.*\/override$/);
});
});
@ -659,7 +658,6 @@ test("Queries in workflow file can be used in tandem with the 'disable default q
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -673,14 +671,17 @@ test("Queries in workflow file can be used in tandem with the 'disable default q
// but won't be called for the default one since that was disabled
t.deepEqual(resolveQueriesArgs.length, 1);
t.deepEqual(resolveQueriesArgs[0].queries.length, 1);
t.regex(resolveQueriesArgs[0].queries[0], /.*\/workflow-query$/);
t.true(
resolveQueriesArgs[0].queries[0].endsWith(`${path.sep}workflow-query`)
);
// Now check that the end result contains only the workflow query, and not the default one
t.deepEqual(config.queries["javascript"].builtin.length, 0);
t.deepEqual(config.queries["javascript"].custom.length, 1);
t.regex(
config.queries["javascript"].custom[0].queries[0],
/.*\/workflow-query$/
t.true(
config.queries["javascript"].custom[0].queries[0].endsWith(
`${path.sep}workflow-query`
)
);
});
});
@ -719,7 +720,6 @@ test("Multiple queries can be specified in workflow file, no config file require
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -734,23 +734,26 @@ test("Multiple queries can be specified in workflow file, no config file require
t.deepEqual(resolveQueriesArgs.length, 3);
t.deepEqual(resolveQueriesArgs[1].queries.length, 1);
t.deepEqual(resolveQueriesArgs[2].queries.length, 1);
t.regex(resolveQueriesArgs[1].queries[0], /.*\/override1$/);
t.regex(resolveQueriesArgs[2].queries[0], /.*\/override2$/);
t.true(resolveQueriesArgs[1].queries[0].endsWith(`${path.sep}override1`));
t.true(resolveQueriesArgs[2].queries[0].endsWith(`${path.sep}override2`));
// Now check that the end result contains both the queries from the workflow, as well as the defaults
t.deepEqual(config.queries["javascript"].builtin.length, 1);
t.deepEqual(config.queries["javascript"].custom.length, 2);
t.regex(
config.queries["javascript"].builtin[0],
/javascript-code-scanning.qls$/
t.true(
config.queries["javascript"].builtin[0].endsWith(
"javascript-code-scanning.qls"
)
);
t.regex(
config.queries["javascript"].custom[0].queries[0],
/.*\/override1$/
t.true(
config.queries["javascript"].custom[0].queries[0].endsWith(
`${path.sep}override1`
)
);
t.regex(
config.queries["javascript"].custom[1].queries[0],
/.*\/override2$/
t.true(
config.queries["javascript"].custom[1].queries[0].endsWith(
`${path.sep}override2`
)
);
});
});
@ -800,7 +803,6 @@ test("Queries in workflow file can be added to the set of queries without overri
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -815,28 +817,35 @@ test("Queries in workflow file can be added to the set of queries without overri
// and once for './foo' from the config file
t.deepEqual(resolveQueriesArgs.length, 4);
t.deepEqual(resolveQueriesArgs[1].queries.length, 1);
t.regex(resolveQueriesArgs[1].queries[0], /.*\/additional1$/);
t.true(resolveQueriesArgs[1].queries[0].endsWith(`${path.sep}additional1`));
t.deepEqual(resolveQueriesArgs[2].queries.length, 1);
t.regex(resolveQueriesArgs[2].queries[0], /.*\/additional2$/);
t.true(resolveQueriesArgs[2].queries[0].endsWith(`${path.sep}additional2`));
t.deepEqual(resolveQueriesArgs[3].queries.length, 1);
t.regex(resolveQueriesArgs[3].queries[0], /.*\/foo$/);
t.true(resolveQueriesArgs[3].queries[0].endsWith(`${path.sep}foo`));
// Now check that the end result contains all the queries
t.deepEqual(config.queries["javascript"].builtin.length, 1);
t.deepEqual(config.queries["javascript"].custom.length, 3);
t.regex(
config.queries["javascript"].builtin[0],
/javascript-code-scanning.qls$/
t.true(
config.queries["javascript"].builtin[0].endsWith(
"javascript-code-scanning.qls"
)
);
t.regex(
config.queries["javascript"].custom[0].queries[0],
/.*\/additional1$/
t.true(
config.queries["javascript"].custom[0].queries[0].endsWith(
`${path.sep}additional1`
)
);
t.regex(
config.queries["javascript"].custom[1].queries[0],
/.*\/additional2$/
t.true(
config.queries["javascript"].custom[1].queries[0].endsWith(
`${path.sep}additional2`
)
);
t.true(
config.queries["javascript"].custom[2].queries[0].endsWith(
`${path.sep}foo`
)
);
t.regex(config.queries["javascript"].custom[2].queries[0], /.*\/foo$/);
});
});
@ -871,7 +880,6 @@ test("Invalid queries in workflow file handled correctly", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -939,7 +947,6 @@ test("API client used when reading remote config", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -969,7 +976,6 @@ test("Remote config handles the case where a directory is provided", async (t) =
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
getCachedCodeQL(),
tmpDir,
gitHubVersion,
@ -1007,7 +1013,6 @@ test("Invalid format of remote config handled correctly", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
getCachedCodeQL(),
tmpDir,
gitHubVersion,
@ -1046,7 +1051,6 @@ test("No detected languages", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -1077,7 +1081,6 @@ test("Unknown languages", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
getCachedCodeQL(),
tmpDir,
gitHubVersion,
@ -1130,7 +1133,6 @@ test("Config specifies packages", async (t) => {
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -1187,7 +1189,6 @@ test("Config specifies packages for multiple languages", async (t) => {
"",
{ owner: "github", repo: "example" },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -1255,7 +1256,6 @@ function doInvalidInputTest(
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
@ -1785,7 +1785,6 @@ const mlPoweredQueriesMacro = test.macro({
"",
{ owner: "github", repo: "example " },
tmpDir,
tmpDir,
codeQL,
tmpDir,
gitHubVersion,

View file

@ -114,11 +114,6 @@ export interface Config {
* deleted at the end of the job.
*/
tempDir: string;
/**
* Directory to use for the tool cache.
* This may be persisted between jobs but this is not guaranteed.
*/
toolCacheDir: string;
/**
* Path of the CodeQL executable.
*/
@ -921,7 +916,6 @@ export async function getDefaultConfig(
debugDatabaseName: string,
repository: RepositoryNwo,
tempDir: string,
toolCacheDir: string,
codeQL: CodeQL,
workspacePath: string,
gitHubVersion: GitHubVersion,
@ -978,7 +972,6 @@ export async function getDefaultConfig(
packs,
originalUserInput: {},
tempDir,
toolCacheDir,
codeQLCmd: codeQL.getPath(),
gitHubVersion,
dbLocation: dbLocationOrDefault(dbLocation, tempDir),
@ -1003,7 +996,6 @@ async function loadConfig(
debugDatabaseName: string,
repository: RepositoryNwo,
tempDir: string,
toolCacheDir: string,
codeQL: CodeQL,
workspacePath: string,
gitHubVersion: GitHubVersion,
@ -1165,7 +1157,6 @@ async function loadConfig(
packs,
originalUserInput: parsedYAML,
tempDir,
toolCacheDir,
codeQLCmd: codeQL.getPath(),
gitHubVersion,
dbLocation: dbLocationOrDefault(dbLocation, tempDir),
@ -1404,7 +1395,13 @@ export function validatePacksSpecification(
if (
packPath &&
(path.isAbsolute(packPath) || path.normalize(packPath) !== packPath)
(path.isAbsolute(packPath) ||
// Permit using "/" instead of "\" on Windows
// Use `x.split(y).join(z)` as a polyfill for `x.replaceAll(y, z)` since
// if we used a regex we'd need to escape the path separator on Windows
// which seems more awkward.
path.normalize(packPath).split(path.sep).join("/") !==
packPath.split(path.sep).join("/"))
) {
throw new Error(getPacksStrInvalid(packStr, configFile));
}
@ -1503,7 +1500,6 @@ export async function initConfig(
debugDatabaseName: string,
repository: RepositoryNwo,
tempDir: string,
toolCacheDir: string,
codeQL: CodeQL,
workspacePath: string,
gitHubVersion: GitHubVersion,
@ -1526,7 +1522,6 @@ export async function initConfig(
debugDatabaseName,
repository,
tempDir,
toolCacheDir,
codeQL,
workspacePath,
gitHubVersion,
@ -1546,7 +1541,6 @@ export async function initConfig(
debugDatabaseName,
repository,
tempDir,
toolCacheDir,
codeQL,
workspacePath,
gitHubVersion,

View file

@ -48,7 +48,6 @@ function getTestConfig(tmpDir: string): Config {
paths: [],
originalUserInput: {},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: "foo",
gitHubVersion: { type: GitHubVariant.DOTCOM },
dbLocation: tmpDir,

View file

@ -139,19 +139,27 @@ test("resolveUriToFile", (t) => {
// so we need to give it real files to look at. We will use this file as an example.
// For this to work we require the current working directory to be a parent, but this
// should generally always be the case so this is fine.
const cwd = process.cwd();
const filepath = __filename;
t.true(filepath.startsWith(`${cwd}/`));
const relativeFilepath = filepath.substring(cwd.length + 1);
const filepath = __filename.split(path.sep).join("/");
const relativeFilepath = path
.relative(process.cwd(), __filename)
.split(path.sep)
.join("/");
// Absolute paths are unmodified
t.is(testResolveUriToFile(filepath, undefined, []), filepath);
t.is(testResolveUriToFile(`file://${filepath}`, undefined, []), filepath);
// Relative paths are made absolute
t.is(testResolveUriToFile(relativeFilepath, undefined, []), filepath);
t.is(
testResolveUriToFile(`file://${relativeFilepath}`, undefined, []),
testResolveUriToFile(relativeFilepath, undefined, [])
?.split(path.sep)
.join("/"),
filepath
);
t.is(
testResolveUriToFile(`file://${relativeFilepath}`, undefined, [])
?.split(path.sep)
.join("/"),
filepath
);

View file

@ -1,4 +1,5 @@
import * as fs from "fs";
import path from "path";
import Long from "long";
@ -226,7 +227,7 @@ export function resolveUriToFile(
// Just assume a relative path is relative to the src root.
// This is not necessarily true but should be a good approximation
// and here we likely want to err on the side of handling more cases.
if (!uri.startsWith("/")) {
if (!path.isAbsolute(uri)) {
uri = srcRootPrefix + uri;
}

View file

@ -8,7 +8,6 @@ import {
getOptionalInput,
getRequiredInput,
getTemporaryDirectory,
getToolCacheDirectory,
sendStatusReport,
StatusReportBase,
validateWorkflow,
@ -171,7 +170,6 @@ async function run() {
getOptionalInput("tools"),
apiDetails,
getTemporaryDirectory(),
getToolCacheDirectory(),
gitHubVersion.type,
logger
);
@ -185,12 +183,15 @@ async function run() {
getOptionalInput("packs"),
getOptionalInput("config-file"),
getOptionalInput("db-location"),
getOptionalInput("debug") === "true",
// Debug mode is enabled if:
// - The `init` Action is passed `debug: true`.
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),
// or by setting the `ACTIONS_STEP_DEBUG` secret to `true`).
getOptionalInput("debug") === "true" || core.isDebug(),
getOptionalInput("debug-artifact-name") || DEFAULT_DEBUG_ARTIFACT_NAME,
getOptionalInput("debug-database-name") || DEFAULT_DEBUG_DATABASE_NAME,
repositoryNwo,
getTemporaryDirectory(),
getRequiredEnvParam("RUNNER_TOOL_CACHE"),
codeql,
getRequiredEnvParam("GITHUB_WORKSPACE"),
gitHubVersion,

View file

@ -19,7 +19,6 @@ export async function initCodeQL(
codeqlURL: string | undefined,
apiDetails: GitHubApiDetails,
tempDir: string,
toolCacheDir: string,
variant: util.GitHubVariant,
logger: Logger
): Promise<{ codeql: CodeQL; toolsVersion: string }> {
@ -28,7 +27,6 @@ export async function initCodeQL(
codeqlURL,
apiDetails,
tempDir,
toolCacheDir,
variant,
logger,
true
@ -49,7 +47,6 @@ export async function initConfig(
debugDatabaseName: string,
repository: RepositoryNwo,
tempDir: string,
toolCacheDir: string,
codeQL: CodeQL,
workspacePath: string,
gitHubVersion: util.GitHubVersion,
@ -69,7 +66,6 @@ export async function initConfig(
debugDatabaseName,
repository,
tempDir,
toolCacheDir,
codeQL,
workspacePath,
gitHubVersion,
@ -253,11 +249,14 @@ export async function installPythonDeps(codeql: CodeQL, logger: Logger) {
if (process.platform === "win32") {
await new toolrunner.ToolRunner(await safeWhich.safeWhich("py"), [
"-3",
"-B",
path.join(scriptsFolder, script),
path.dirname(codeql.getPath()),
]).exec();
} else {
await new toolrunner.ToolRunner(path.join(scriptsFolder, script), [
await new toolrunner.ToolRunner(await safeWhich.safeWhich("python3"), [
"-B",
path.join(scriptsFolder, script),
path.dirname(codeql.getPath()),
]).exec();
}

View file

@ -1,5 +1,4 @@
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import { Command } from "commander";
@ -47,14 +46,6 @@ function getTempDir(userInput: string | undefined): string {
return tempDir;
}
function getToolsDir(userInput: string | undefined): string {
const toolsDir = userInput || path.join(os.homedir(), "codeql-runner-tools");
if (!fs.existsSync(toolsDir)) {
fs.mkdirSync(toolsDir, { recursive: true });
}
return toolsDir;
}
const codeqlEnvJsonFilename = "codeql-env.json";
function loadTracerEnvironment(config: Config): { [name: string]: string } {
@ -194,7 +185,6 @@ program
try {
const tempDir = getTempDir(cmd.tempDir);
const toolsDir = getToolsDir(cmd.toolsDir);
const checkoutPath = cmd.checkoutPath || process.cwd();
// Wipe the temp dir
@ -237,7 +227,6 @@ program
undefined,
apiDetails,
tempDir,
toolsDir,
gitHubVersion.type,
logger
)
@ -256,7 +245,6 @@ program
"",
parseRepositoryNwo(cmd.repository),
tempDir,
toolsDir,
codeql,
workspacePath,
gitHubVersion,

View file

@ -63,6 +63,16 @@ export function setupTests(test: TestFn<any>) {
t.context.stderrWrite = processStderrWrite;
process.stderr.write = wrapOutput(t.context) as any;
// Workaround an issue in tests where the case insensitivity of the `$PATH`
// environment variable on Windows isn't preserved, i.e. `process.env.PATH`
// is not the same as `process.env.Path`.
const pathKeys = Object.keys(process.env).filter(
(k) => k.toLowerCase() === "path"
);
if (pathKeys.length > 0) {
process.env.PATH = process.env[pathKeys[0]];
}
// Many tests modify environment variables. Take a copy now so that
// we reset them after the test to keep tests independent of each other.
// process.env only has strings fields, so a shallow copy is fine.

View file

@ -1,337 +0,0 @@
import * as fs from "fs";
import { OutgoingHttpHeaders } from "http";
import * as os from "os";
import * as path from "path";
import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as io from "@actions/io";
import * as actionsToolcache from "@actions/tool-cache";
import * as safeWhich from "@chrisgavin/safe-which";
import del from "del";
import * as semver from "semver";
import { v4 as uuidV4 } from "uuid";
import { Logger } from "./logging";
import { isActions } from "./util";
/*
* This file acts as an interface to the functionality of the actions toolcache.
* That library is not safe to use outside of actions as it makes assumptions about
* the state of the filesystem and available environment variables.
*
* On actions we can just delegate to the toolcache library, however outside of
* actions we provide our own implementation.
*/
/**
* Extract a compressed tar archive.
*
* See extractTar function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
*
* @param file path to the tar
* @param mode should run the actions or runner implementation
* @param tempDir path to the temporary directory
* @param logger logger to use
* @returns path to the destination directory
*/
export async function extractTar(
file: string,
tempDir: string,
logger: Logger
): Promise<string> {
if (isActions()) {
return await actionsToolcache.extractTar(file);
} else {
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
if (!file) {
throw new Error("parameter 'file' is required");
}
// Create dest
const dest = createExtractFolder(tempDir);
// Determine whether GNU tar
logger.debug("Checking tar --version");
let versionOutput = "";
await new toolrunner.ToolRunner(
await safeWhich.safeWhich("tar"),
["--version"],
{
ignoreReturnCode: true,
silent: true,
listeners: {
stdout: (data) => (versionOutput += data.toString()),
stderr: (data) => (versionOutput += data.toString()),
},
}
).exec();
logger.debug(versionOutput.trim());
const isGnuTar = versionOutput.toUpperCase().includes("GNU TAR");
// Initialize args
const args = ["xz"];
if (logger.isDebug()) {
args.push("-v");
}
let destArg = dest;
let fileArg = file;
if (process.platform === "win32" && isGnuTar) {
args.push("--force-local");
destArg = dest.replace(/\\/g, "/");
// Technically only the dest needs to have `/` but for aesthetic consistency
// convert slashes in the file arg too.
fileArg = file.replace(/\\/g, "/");
}
if (isGnuTar) {
// Suppress warnings when using GNU tar to extract archives created by BSD tar
args.push("--warning=no-unknown-keyword");
}
args.push("-C", destArg, "-f", fileArg);
await new toolrunner.ToolRunner(`tar`, args).exec();
return dest;
}
}
/**
* Caches a directory and installs it into the tool cacheDir.
*
* Also see cacheDir function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
*
* @param sourceDir the directory to cache into tools
* @param tool tool name
* @param version version of the tool. semver format
* @param mode should run the actions or runner implementation
* @param toolCacheDir path to the tool cache directory
* @param logger logger to use
*/
export async function cacheDir(
sourceDir: string,
tool: string,
version: string,
toolCacheDir: string,
logger: Logger
): Promise<string> {
if (isActions()) {
return await actionsToolcache.cacheDir(sourceDir, tool, version);
} else {
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
version = semver.clean(version) || version;
const arch = os.arch();
logger.debug(`Caching tool ${tool} ${version} ${arch}`);
logger.debug(`source dir: ${sourceDir}`);
if (!fs.statSync(sourceDir).isDirectory()) {
throw new Error("sourceDir is not a directory");
}
// Create the tool dir
const destPath = await createToolPath(
tool,
version,
arch,
toolCacheDir,
logger
);
// copy each child item. do not move. move can fail on Windows
// due to anti-virus software having an open handle on a file.
for (const itemName of fs.readdirSync(sourceDir)) {
const s = path.join(sourceDir, itemName);
await io.cp(s, destPath, { recursive: true });
}
// write .complete
completeToolPath(tool, version, arch, toolCacheDir, logger);
return destPath;
}
}
/**
* Finds the path to a tool version in the local installed tool cache.
*
* Also see find function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
*
* @param toolName name of the tool
* @param versionSpec version of the tool
* @param mode should run the actions or runner implementation
* @param toolCacheDir path to the tool cache directory
* @param logger logger to use
*/
export function find(
toolName: string,
versionSpec: string,
toolCacheDir: string,
logger: Logger
): string {
if (isActions()) {
return actionsToolcache.find(toolName, versionSpec);
} else {
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
if (!toolName) {
throw new Error("toolName parameter is required");
}
if (!versionSpec) {
throw new Error("versionSpec parameter is required");
}
const arch = os.arch();
// attempt to resolve an explicit version
if (!isExplicitVersion(versionSpec, logger)) {
const localVersions = findAllVersions(toolName, toolCacheDir, logger);
const match = evaluateVersions(localVersions, versionSpec, logger);
versionSpec = match;
}
// check for the explicit version in the cache
let toolPath = "";
if (versionSpec) {
versionSpec = semver.clean(versionSpec) || "";
const cachePath = path.join(toolCacheDir, toolName, versionSpec, arch);
logger.debug(`checking cache: ${cachePath}`);
if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) {
logger.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`);
toolPath = cachePath;
} else {
logger.debug("not found");
}
}
return toolPath;
}
}
/**
* Finds the paths to all versions of a tool that are installed in the local tool cache.
*
* Also see findAllVersions function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
*
* @param toolName name of the tool
* @param toolCacheDir path to the tool cache directory
* @param logger logger to use
*/
export function findAllVersions(
toolName: string,
toolCacheDir: string,
logger: Logger
): string[] {
if (isActions()) {
return actionsToolcache.findAllVersions(toolName);
} else {
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
const versions: string[] = [];
const arch = os.arch();
const toolPath = path.join(toolCacheDir, toolName);
if (fs.existsSync(toolPath)) {
const children = fs.readdirSync(toolPath);
for (const child of children) {
if (isExplicitVersion(child, logger)) {
const fullPath = path.join(toolPath, child, arch || "");
if (
fs.existsSync(fullPath) &&
fs.existsSync(`${fullPath}.complete`)
) {
versions.push(child);
}
}
}
}
return versions;
}
}
export async function downloadTool(
url: string,
tempDir: string,
headers: OutgoingHttpHeaders
): Promise<string> {
const dest = path.join(tempDir, uuidV4());
const finalHeaders = Object.assign(
{ "User-Agent": "CodeQL Action" },
headers
);
return await actionsToolcache.downloadTool(
url,
dest,
undefined,
finalHeaders
);
}
function createExtractFolder(tempDir: string): string {
// create a temp dir
const dest = path.join(tempDir, "toolcache-temp");
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest);
}
return dest;
}
async function createToolPath(
tool: string,
version: string,
arch: string,
toolCacheDir: string,
logger: Logger
): Promise<string> {
const folderPath = path.join(
toolCacheDir,
tool,
semver.clean(version) || version,
arch || ""
);
logger.debug(`destination ${folderPath}`);
const markerPath = `${folderPath}.complete`;
await del(folderPath, { force: true });
await del(markerPath, { force: true });
fs.mkdirSync(folderPath, { recursive: true });
return folderPath;
}
function completeToolPath(
tool: string,
version: string,
arch: string,
toolCacheDir: string,
logger: Logger
) {
const folderPath = path.join(
toolCacheDir,
tool,
semver.clean(version) || version,
arch || ""
);
const markerPath = `${folderPath}.complete`;
fs.writeFileSync(markerPath, "");
logger.debug("finished caching tool");
}
function isExplicitVersion(versionSpec: string, logger: Logger) {
const c = semver.clean(versionSpec) || "";
logger.debug(`isExplicit: ${c}`);
const valid = semver.valid(c) != null;
logger.debug(`explicit? ${valid}`);
return valid;
}
function evaluateVersions(
versions: string[],
versionSpec: string,
logger: Logger
): string {
let version = "";
logger.debug(`evaluating ${versions.length} versions`);
versions = versions.sort((a, b) => {
if (semver.gt(a, b)) {
return 1;
}
return -1;
});
for (let i = versions.length - 1; i >= 0; i--) {
const potential = versions[i];
const satisfied = semver.satisfies(potential, versionSpec);
if (satisfied) {
version = potential;
break;
}
}
if (version) {
logger.debug(`matched: ${version}`);
} else {
logger.debug("match not found");
}
return version;
}

View file

@ -24,7 +24,6 @@ function getTestConfig(tmpDir: string): configUtils.Config {
paths: [],
originalUserInput: {},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM } as util.GitHubVersion,
dbLocation: path.resolve(tmpDir, "codeql_databases"),

View file

@ -335,7 +335,6 @@ for (const [packs, expectedStatus] of ML_POWERED_JS_STATUS_TESTS) {
pathsIgnore: [],
originalUserInput: {},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: "",
gitHubVersion: {
type: util.GitHubVariant.DOTCOM,

View file

@ -116,11 +116,7 @@ export async function withTmpDir<T>(
body: (tmpDir: string) => Promise<T>
): Promise<T> {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "codeql-action-"));
const realSubdir = path.join(tmpDir, "real");
fs.mkdirSync(realSubdir);
const symlinkSubdir = path.join(tmpDir, "symlink");
fs.symlinkSync(realSubdir, symlinkSubdir, "dir");
const result = await body(symlinkSubdir);
const result = await body(tmpDir);
await del(tmpDir, { force: true });
return result;
}