mirror of
https://github.com/github/codeql-action.git
synced 2025-12-08 08:48:19 +08:00
Compare commits
2 Commits
codeql-bun
...
daverlo/ge
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a50226279 | ||
|
|
382c51457f |
27
lib/config-utils.js
generated
27
lib/config-utils.js
generated
@@ -275,14 +275,10 @@ function getConfigFileRepoFormatInvalidMessage(configFile) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
exports.getConfigFileRepoFormatInvalidMessage = getConfigFileRepoFormatInvalidMessage;
|
exports.getConfigFileRepoFormatInvalidMessage = getConfigFileRepoFormatInvalidMessage;
|
||||||
function getConfigFileFormatInvalidMessage(configFile) {
|
function getConfigFileFormatInvalidMessage(configFile, reason) {
|
||||||
return 'The configuration file "' + configFile + '" could not be read';
|
return 'The configuration file "' + configFile + '" could not be read. Reason: ' + reason;
|
||||||
}
|
}
|
||||||
exports.getConfigFileFormatInvalidMessage = getConfigFileFormatInvalidMessage;
|
exports.getConfigFileFormatInvalidMessage = getConfigFileFormatInvalidMessage;
|
||||||
function getConfigFileDirectoryGivenMessage(configFile) {
|
|
||||||
return 'The configuration file "' + configFile + '" looks like a directory, not a file';
|
|
||||||
}
|
|
||||||
exports.getConfigFileDirectoryGivenMessage = getConfigFileDirectoryGivenMessage;
|
|
||||||
function getConfigFilePropertyError(configFile, property, error) {
|
function getConfigFilePropertyError(configFile, property, error) {
|
||||||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||||
}
|
}
|
||||||
@@ -538,23 +534,14 @@ async function getRemoteConfig(configFile) {
|
|||||||
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
|
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
|
||||||
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
||||||
}
|
}
|
||||||
const response = await api.getActionsApiClient(true).repos.getContents({
|
|
||||||
owner: pieces.groups.owner,
|
|
||||||
repo: pieces.groups.repo,
|
|
||||||
path: pieces.groups.path,
|
|
||||||
ref: pieces.groups.ref,
|
|
||||||
});
|
|
||||||
let fileContents;
|
let fileContents;
|
||||||
if ("content" in response.data && response.data.content !== undefined) {
|
try {
|
||||||
fileContents = response.data.content;
|
fileContents = await util.getFileContentsUsingAPI(pieces.groups.owner, pieces.groups.repo, pieces.groups.path, pieces.groups.ref);
|
||||||
}
|
}
|
||||||
else if (Array.isArray(response.data)) {
|
catch (err) {
|
||||||
throw new Error(getConfigFileDirectoryGivenMessage(configFile));
|
throw new Error(getConfigFileFormatInvalidMessage(configFile, err.message));
|
||||||
}
|
}
|
||||||
else {
|
return yaml.safeLoad(fileContents);
|
||||||
throw new Error(getConfigFileFormatInvalidMessage(configFile));
|
|
||||||
}
|
|
||||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get the file path where the parsed config will be stored.
|
* Get the file path where the parsed config will be stored.
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
26
lib/config-utils.test.js
generated
26
lib/config-utils.test.js
generated
@@ -18,9 +18,9 @@ const sinon_1 = __importDefault(require("sinon"));
|
|||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
const CodeQL = __importStar(require("./codeql"));
|
const CodeQL = __importStar(require("./codeql"));
|
||||||
const configUtils = __importStar(require("./config-utils"));
|
const configUtils = __importStar(require("./config-utils"));
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testingUtils = __importStar(require("./testing-utils"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
testing_utils_1.setupTests(ava_1.default);
|
testingUtils.setupTests(ava_1.default);
|
||||||
function setInput(name, value) {
|
function setInput(name, value) {
|
||||||
// Transformation copied from
|
// Transformation copied from
|
||||||
// https://github.com/actions/toolkit/blob/05e39f551d33e1688f61b209ab5cdd335198f1b8/packages/core/src/core.ts#L69
|
// https://github.com/actions/toolkit/blob/05e39f551d33e1688f61b209ab5cdd335198f1b8/packages/core/src/core.ts#L69
|
||||||
@@ -32,16 +32,6 @@ function setInput(name, value) {
|
|||||||
delete process.env[envVar];
|
delete process.env[envVar];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function mockGetContents(content) {
|
|
||||||
// Passing an auth token is required, so we just use a dummy value
|
|
||||||
let client = new github.GitHub('123');
|
|
||||||
const response = {
|
|
||||||
data: content
|
|
||||||
};
|
|
||||||
const spyGetContents = sinon_1.default.stub(client.repos, "getContents").resolves(response);
|
|
||||||
sinon_1.default.stub(api, "getApiClient").value(() => client);
|
|
||||||
return spyGetContents;
|
|
||||||
}
|
|
||||||
function mockListLanguages(languages) {
|
function mockListLanguages(languages) {
|
||||||
// Passing an auth token is required, so we just use a dummy value
|
// Passing an auth token is required, so we just use a dummy value
|
||||||
let client = new github.GitHub('123');
|
let client = new github.GitHub('123');
|
||||||
@@ -270,7 +260,7 @@ ava_1.default("API client used when reading remote config", async (t) => {
|
|||||||
const dummyResponse = {
|
const dummyResponse = {
|
||||||
content: Buffer.from(inputFileContents).toString("base64"),
|
content: Buffer.from(inputFileContents).toString("base64"),
|
||||||
};
|
};
|
||||||
const spyGetContents = mockGetContents(dummyResponse);
|
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
// Create checkout directory for remote queries repository
|
// Create checkout directory for remote queries repository
|
||||||
fs.mkdirSync(path.join(tmpDir, 'foo/bar'), { recursive: true });
|
fs.mkdirSync(path.join(tmpDir, 'foo/bar'), { recursive: true });
|
||||||
setInput('config-file', 'octo-org/codeql-config/config.yaml@main');
|
setInput('config-file', 'octo-org/codeql-config/config.yaml@main');
|
||||||
@@ -284,7 +274,7 @@ ava_1.default("Remote config handles the case where a directory is provided", as
|
|||||||
process.env['RUNNER_TEMP'] = tmpDir;
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
const dummyResponse = []; // directories are returned as arrays
|
const dummyResponse = []; // directories are returned as arrays
|
||||||
mockGetContents(dummyResponse);
|
testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||||
setInput('config-file', repoReference);
|
setInput('config-file', repoReference);
|
||||||
try {
|
try {
|
||||||
@@ -292,7 +282,8 @@ ava_1.default("Remote config handles the case where a directory is provided", as
|
|||||||
throw new Error('initConfig did not throw error');
|
throw new Error('initConfig did not throw error');
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
t.deepEqual(err, new Error(configUtils.getConfigFileDirectoryGivenMessage(repoReference)));
|
const reason = util.fileIsADirectoryError(repoReference);
|
||||||
|
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference, reason)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -303,7 +294,7 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
|
|||||||
const dummyResponse = {
|
const dummyResponse = {
|
||||||
// note no "content" property here
|
// note no "content" property here
|
||||||
};
|
};
|
||||||
mockGetContents(dummyResponse);
|
testingUtils.mockGetContents(dummyResponse, 400);
|
||||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||||
setInput('config-file', repoReference);
|
setInput('config-file', repoReference);
|
||||||
try {
|
try {
|
||||||
@@ -311,7 +302,8 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
|
|||||||
throw new Error('initConfig did not throw error');
|
throw new Error('initConfig did not throw error');
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference)));
|
const reason = util.fileDownloadError(repoReference);
|
||||||
|
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference, reason)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
20
lib/testing-utils.js
generated
20
lib/testing-utils.js
generated
@@ -1,7 +1,4 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
if (mod && mod.__esModule) return mod;
|
if (mod && mod.__esModule) return mod;
|
||||||
var result = {};
|
var result = {};
|
||||||
@@ -9,8 +6,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
result["default"] = mod;
|
result["default"] = mod;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const github = __importStar(require("@actions/github"));
|
||||||
const sinon_1 = __importDefault(require("sinon"));
|
const sinon_1 = __importDefault(require("sinon"));
|
||||||
|
const api = __importStar(require("./api-client"));
|
||||||
const CodeQL = __importStar(require("./codeql"));
|
const CodeQL = __importStar(require("./codeql"));
|
||||||
function wrapOutput(context) {
|
function wrapOutput(context) {
|
||||||
// Function signature taken from Socket.write.
|
// Function signature taken from Socket.write.
|
||||||
@@ -75,4 +77,16 @@ function setupTests(test) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.setupTests = setupTests;
|
exports.setupTests = setupTests;
|
||||||
|
function mockGetContents(content, status) {
|
||||||
|
// Passing an auth token is required, so we just use a dummy value
|
||||||
|
let client = new github.GitHub('123');
|
||||||
|
const response = {
|
||||||
|
data: content,
|
||||||
|
status: status
|
||||||
|
};
|
||||||
|
const spyGetContents = sinon_1.default.stub(client.repos, "getContents").resolves(response);
|
||||||
|
sinon_1.default.stub(api, "getApiClient").value(() => client);
|
||||||
|
return spyGetContents;
|
||||||
|
}
|
||||||
|
exports.mockGetContents = mockGetContents;
|
||||||
//# sourceMappingURL=testing-utils.js.map
|
//# sourceMappingURL=testing-utils.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"testing-utils.js","sourceRoot":"","sources":["../src/testing-utils.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"testing-utils.js","sourceRoot":"","sources":["../src/testing-utils.ts"],"names":[],"mappings":"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"}
|
||||||
32
lib/util.js
generated
32
lib/util.js
generated
@@ -378,4 +378,36 @@ function getCodeQLDatabasesDir() {
|
|||||||
return path.resolve(getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
return path.resolve(getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
||||||
}
|
}
|
||||||
exports.getCodeQLDatabasesDir = getCodeQLDatabasesDir;
|
exports.getCodeQLDatabasesDir = getCodeQLDatabasesDir;
|
||||||
|
function fileDownloadError(file) {
|
||||||
|
return 'Error while trying to download `' + file + '`';
|
||||||
|
}
|
||||||
|
exports.fileDownloadError = fileDownloadError;
|
||||||
|
function fileIsADirectoryError(file) {
|
||||||
|
return '`' + file + '` is a directory';
|
||||||
|
}
|
||||||
|
exports.fileIsADirectoryError = fileIsADirectoryError;
|
||||||
|
async function getFileContentsUsingAPI(owner, repo, path, ref) {
|
||||||
|
const response = await api.getActionsApiClient(true).repos.getContents({
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
path: path,
|
||||||
|
ref: ref,
|
||||||
|
});
|
||||||
|
const file = [owner, repo, path].join('/') + '@' + ref;
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(fileDownloadError(file));
|
||||||
|
}
|
||||||
|
if (Array.isArray(response.data)) {
|
||||||
|
throw new Error(fileIsADirectoryError(file));
|
||||||
|
}
|
||||||
|
let fileContents;
|
||||||
|
if ("content" in response.data && response.data.content !== undefined) {
|
||||||
|
fileContents = response.data.content;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error(fileDownloadError(file));
|
||||||
|
}
|
||||||
|
return Buffer.from(fileContents, 'base64').toString('binary');
|
||||||
|
}
|
||||||
|
exports.getFileContentsUsingAPI = getFileContentsUsingAPI;
|
||||||
//# sourceMappingURL=util.js.map
|
//# sourceMappingURL=util.js.map
|
||||||
File diff suppressed because one or more lines are too long
37
lib/util.test.js
generated
37
lib/util.test.js
generated
@@ -13,9 +13,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const os = __importStar(require("os"));
|
const os = __importStar(require("os"));
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testingUtils = __importStar(require("./testing-utils"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
testing_utils_1.setupTests(ava_1.default);
|
testingUtils.setupTests(ava_1.default);
|
||||||
ava_1.default('getToolNames', t => {
|
ava_1.default('getToolNames', t => {
|
||||||
const input = fs.readFileSync(__dirname + '/../src/testdata/tool-names.sarif', 'utf8');
|
const input = fs.readFileSync(__dirname + '/../src/testdata/tool-names.sarif', 'utf8');
|
||||||
const toolNames = util.getToolNames(input);
|
const toolNames = util.getToolNames(input);
|
||||||
@@ -113,4 +113,37 @@ ava_1.default('getExtraOptionsEnvParam() fails on invalid JSON', t => {
|
|||||||
t.throws(util.getExtraOptionsEnvParam);
|
t.throws(util.getExtraOptionsEnvParam);
|
||||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
||||||
});
|
});
|
||||||
|
ava_1.default('getFileContentsUsingAPI() throws if the request does not succeed', async (t) => {
|
||||||
|
const spyGetContents = testingUtils.mockGetContents({}, 400);
|
||||||
|
try {
|
||||||
|
await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
t.assert(spyGetContents.called);
|
||||||
|
t.deepEqual(err, new Error(util.fileDownloadError('github/codeql-action/non-existing-file@main')));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ava_1.default('getFileContentsUsingAPI() throws if the requested file is a directory', async (t) => {
|
||||||
|
const dummyResponse = []; // directories are returned as arrays
|
||||||
|
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
|
try {
|
||||||
|
await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
t.assert(spyGetContents.called);
|
||||||
|
t.deepEqual(err, new Error(util.fileIsADirectoryError('github/codeql-action/non-existing-file@main')));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ava_1.default('getFileContentsUsingAPI() returns the right content', async (t) => {
|
||||||
|
const inputFileContents = `content content content`;
|
||||||
|
const dummyResponse = {
|
||||||
|
content: Buffer.from(inputFileContents).toString("base64"),
|
||||||
|
};
|
||||||
|
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
|
const content = await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||||
|
t.deepEqual(content, inputFileContents);
|
||||||
|
t.assert(spyGetContents.called);
|
||||||
|
});
|
||||||
//# sourceMappingURL=util.test.js.map
|
//# sourceMappingURL=util.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -7,10 +7,10 @@ import sinon from 'sinon';
|
|||||||
import * as api from './api-client';
|
import * as api from './api-client';
|
||||||
import * as CodeQL from './codeql';
|
import * as CodeQL from './codeql';
|
||||||
import * as configUtils from './config-utils';
|
import * as configUtils from './config-utils';
|
||||||
import {setupTests} from './testing-utils';
|
import * as testingUtils from './testing-utils';
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
|
|
||||||
setupTests(test);
|
testingUtils.setupTests(test);
|
||||||
|
|
||||||
function setInput(name: string, value: string | undefined) {
|
function setInput(name: string, value: string | undefined) {
|
||||||
// Transformation copied from
|
// Transformation copied from
|
||||||
@@ -23,19 +23,6 @@ function setInput(name: string, value: string | undefined) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetContentsResponse = { content?: string; } | {}[];
|
|
||||||
|
|
||||||
function mockGetContents(content: GetContentsResponse): sinon.SinonStub<any, any> {
|
|
||||||
// Passing an auth token is required, so we just use a dummy value
|
|
||||||
let client = new github.GitHub('123');
|
|
||||||
const response = {
|
|
||||||
data: content
|
|
||||||
};
|
|
||||||
const spyGetContents = sinon.stub(client.repos, "getContents").resolves(response as any);
|
|
||||||
sinon.stub(api, "getApiClient").value(() => client);
|
|
||||||
return spyGetContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mockListLanguages(languages: string[]) {
|
function mockListLanguages(languages: string[]) {
|
||||||
// Passing an auth token is required, so we just use a dummy value
|
// Passing an auth token is required, so we just use a dummy value
|
||||||
let client = new github.GitHub('123');
|
let client = new github.GitHub('123');
|
||||||
@@ -303,7 +290,7 @@ test("API client used when reading remote config", async t => {
|
|||||||
const dummyResponse = {
|
const dummyResponse = {
|
||||||
content: Buffer.from(inputFileContents).toString("base64"),
|
content: Buffer.from(inputFileContents).toString("base64"),
|
||||||
};
|
};
|
||||||
const spyGetContents = mockGetContents(dummyResponse);
|
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
|
|
||||||
// Create checkout directory for remote queries repository
|
// Create checkout directory for remote queries repository
|
||||||
fs.mkdirSync(path.join(tmpDir, 'foo/bar'), { recursive: true });
|
fs.mkdirSync(path.join(tmpDir, 'foo/bar'), { recursive: true });
|
||||||
@@ -322,7 +309,7 @@ test("Remote config handles the case where a directory is provided", async t =>
|
|||||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
|
|
||||||
const dummyResponse = []; // directories are returned as arrays
|
const dummyResponse = []; // directories are returned as arrays
|
||||||
mockGetContents(dummyResponse);
|
testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
|
|
||||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||||
setInput('config-file', repoReference);
|
setInput('config-file', repoReference);
|
||||||
@@ -330,7 +317,8 @@ test("Remote config handles the case where a directory is provided", async t =>
|
|||||||
await configUtils.initConfig();
|
await configUtils.initConfig();
|
||||||
throw new Error('initConfig did not throw error');
|
throw new Error('initConfig did not throw error');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
t.deepEqual(err, new Error(configUtils.getConfigFileDirectoryGivenMessage(repoReference)));
|
const reason = util.fileIsADirectoryError(repoReference);
|
||||||
|
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference, reason)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -343,7 +331,7 @@ test("Invalid format of remote config handled correctly", async t => {
|
|||||||
const dummyResponse = {
|
const dummyResponse = {
|
||||||
// note no "content" property here
|
// note no "content" property here
|
||||||
};
|
};
|
||||||
mockGetContents(dummyResponse);
|
testingUtils.mockGetContents(dummyResponse, 400);
|
||||||
|
|
||||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||||
setInput('config-file', repoReference);
|
setInput('config-file', repoReference);
|
||||||
@@ -351,7 +339,8 @@ test("Invalid format of remote config handled correctly", async t => {
|
|||||||
await configUtils.initConfig();
|
await configUtils.initConfig();
|
||||||
throw new Error('initConfig did not throw error');
|
throw new Error('initConfig did not throw error');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference)));
|
const reason = util.fileDownloadError(repoReference);
|
||||||
|
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference, reason)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -399,12 +399,8 @@ export function getConfigFileRepoFormatInvalidMessage(configFile: string): strin
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getConfigFileFormatInvalidMessage(configFile: string): string {
|
export function getConfigFileFormatInvalidMessage(configFile: string, reason: string): string {
|
||||||
return 'The configuration file "' + configFile + '" could not be read';
|
return 'The configuration file "' + configFile + '" could not be read. Reason: ' + reason;
|
||||||
}
|
|
||||||
|
|
||||||
export function getConfigFileDirectoryGivenMessage(configFile: string): string {
|
|
||||||
return 'The configuration file "' + configFile + '" looks like a directory, not a file';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConfigFilePropertyError(configFile: string, property: string, error: string): string {
|
function getConfigFilePropertyError(configFile: string, property: string, error: string): string {
|
||||||
@@ -689,23 +685,18 @@ async function getRemoteConfig(configFile: string): Promise<UserConfig> {
|
|||||||
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await api.getActionsApiClient(true).repos.getContents({
|
|
||||||
owner: pieces.groups.owner,
|
|
||||||
repo: pieces.groups.repo,
|
|
||||||
path: pieces.groups.path,
|
|
||||||
ref: pieces.groups.ref,
|
|
||||||
});
|
|
||||||
|
|
||||||
let fileContents: string;
|
let fileContents: string;
|
||||||
if ("content" in response.data && response.data.content !== undefined) {
|
try {
|
||||||
fileContents = response.data.content;
|
fileContents = await util.getFileContentsUsingAPI(
|
||||||
} else if (Array.isArray(response.data)) {
|
pieces.groups.owner,
|
||||||
throw new Error(getConfigFileDirectoryGivenMessage(configFile));
|
pieces.groups.repo,
|
||||||
} else {
|
pieces.groups.path,
|
||||||
throw new Error(getConfigFileFormatInvalidMessage(configFile));
|
pieces.groups.ref);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(getConfigFileFormatInvalidMessage(configFile, err.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
return yaml.safeLoad(fileContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import * as github from "@actions/github";
|
||||||
import {TestInterface} from 'ava';
|
import {TestInterface} from 'ava';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
|
import * as api from './api-client';
|
||||||
import * as CodeQL from './codeql';
|
import * as CodeQL from './codeql';
|
||||||
|
|
||||||
type TestContext = {stdoutWrite: any, stderrWrite: any, testOutput: string, env: NodeJS.ProcessEnv};
|
type TestContext = {stdoutWrite: any, stderrWrite: any, testOutput: string, env: NodeJS.ProcessEnv};
|
||||||
@@ -77,3 +79,18 @@ export function setupTests(test: TestInterface<any>) {
|
|||||||
process.env = t.context.env;
|
process.env = t.context.env;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GetContentsResponse = { content?: string; } | {}[];
|
||||||
|
|
||||||
|
export function mockGetContents(content: GetContentsResponse, status: number): sinon.SinonStub<any, any> {
|
||||||
|
// Passing an auth token is required, so we just use a dummy value
|
||||||
|
let client = new github.GitHub('123');
|
||||||
|
const response = {
|
||||||
|
data: content,
|
||||||
|
status: status
|
||||||
|
};
|
||||||
|
|
||||||
|
const spyGetContents = sinon.stub(client.repos, "getContents").resolves(response as any);
|
||||||
|
sinon.stub(api, "getApiClient").value(() => client);
|
||||||
|
return spyGetContents;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ import test from 'ava';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
|
|
||||||
import {setupTests} from './testing-utils';
|
|
||||||
|
import * as testingUtils from './testing-utils';
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
|
|
||||||
setupTests(test);
|
testingUtils.setupTests(test);
|
||||||
|
|
||||||
test('getToolNames', t => {
|
test('getToolNames', t => {
|
||||||
const input = fs.readFileSync(__dirname + '/../src/testdata/tool-names.sarif', 'utf8');
|
const input = fs.readFileSync(__dirname + '/../src/testdata/tool-names.sarif', 'utf8');
|
||||||
@@ -150,3 +151,38 @@ test('getExtraOptionsEnvParam() fails on invalid JSON', t => {
|
|||||||
|
|
||||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getFileContentsUsingAPI() throws if the request does not succeed', async t => {
|
||||||
|
const spyGetContents = testingUtils.mockGetContents({}, 400);
|
||||||
|
try {
|
||||||
|
await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
} catch (err) {
|
||||||
|
t.assert(spyGetContents.called);
|
||||||
|
t.deepEqual(err, new Error(util.fileDownloadError('github/codeql-action/non-existing-file@main')));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getFileContentsUsingAPI() throws if the requested file is a directory', async t => {
|
||||||
|
const dummyResponse = []; // directories are returned as arrays
|
||||||
|
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
|
try {
|
||||||
|
await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
} catch (err) {
|
||||||
|
t.assert(spyGetContents.called);
|
||||||
|
t.deepEqual(err, new Error(util.fileIsADirectoryError('github/codeql-action/non-existing-file@main')));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getFileContentsUsingAPI() returns the right content', async t => {
|
||||||
|
const inputFileContents = `content content content`;
|
||||||
|
const dummyResponse = {
|
||||||
|
content: Buffer.from(inputFileContents).toString("base64"),
|
||||||
|
};
|
||||||
|
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||||
|
const content = await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||||
|
|
||||||
|
t.deepEqual(content, inputFileContents);
|
||||||
|
t.assert(spyGetContents.called);
|
||||||
|
});
|
||||||
|
|||||||
36
src/util.ts
36
src/util.ts
@@ -433,3 +433,39 @@ export function getThreadsFlag(): string {
|
|||||||
export function getCodeQLDatabasesDir() {
|
export function getCodeQLDatabasesDir() {
|
||||||
return path.resolve(getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
return path.resolve(getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fileDownloadError(file: string): string {
|
||||||
|
return 'Error while trying to download `' + file + '`';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fileIsADirectoryError(file: string): string {
|
||||||
|
return '`' + file + '` is a directory';
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getFileContentsUsingAPI(owner: string, repo: string, path: string, ref: string): Promise<string> {
|
||||||
|
const response = await api.getActionsApiClient(true).repos.getContents({
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
path: path,
|
||||||
|
ref: ref,
|
||||||
|
});
|
||||||
|
|
||||||
|
const file = [owner, repo, path].join('/') + '@' + ref;
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(fileDownloadError(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(response.data)) {
|
||||||
|
throw new Error(fileIsADirectoryError(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileContents: string;
|
||||||
|
if ("content" in response.data && response.data.content !== undefined) {
|
||||||
|
fileContents = response.data.content;
|
||||||
|
} else {
|
||||||
|
throw new Error(fileDownloadError(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer.from(fileContents, 'base64').toString('binary');
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user