mirror of
https://github.com/github/codeql-action.git
synced 2026-05-08 06:40:19 +00:00
Make config-util.getRemoteConfig use util.getFileContentsUsingAPI
This commit is contained in:
@@ -7,10 +7,10 @@ import sinon from 'sinon';
|
||||
import * as api from './api-client';
|
||||
import * as CodeQL from './codeql';
|
||||
import * as configUtils from './config-utils';
|
||||
import {setupTests} from './testing-utils';
|
||||
import * as testingUtils from './testing-utils';
|
||||
import * as util from './util';
|
||||
|
||||
setupTests(test);
|
||||
testingUtils.setupTests(test);
|
||||
|
||||
function setInput(name: string, value: string | undefined) {
|
||||
// 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[]) {
|
||||
// Passing an auth token is required, so we just use a dummy value
|
||||
let client = new github.GitHub('123');
|
||||
@@ -303,7 +290,7 @@ test("API client used when reading remote config", async t => {
|
||||
const dummyResponse = {
|
||||
content: Buffer.from(inputFileContents).toString("base64"),
|
||||
};
|
||||
const spyGetContents = mockGetContents(dummyResponse);
|
||||
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||
|
||||
// Create checkout directory for remote queries repository
|
||||
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;
|
||||
|
||||
const dummyResponse = []; // directories are returned as arrays
|
||||
mockGetContents(dummyResponse);
|
||||
testingUtils.mockGetContents(dummyResponse, 200);
|
||||
|
||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||
setInput('config-file', repoReference);
|
||||
@@ -330,7 +317,8 @@ test("Remote config handles the case where a directory is provided", async t =>
|
||||
await configUtils.initConfig();
|
||||
throw new Error('initConfig did not throw error');
|
||||
} 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 = {
|
||||
// note no "content" property here
|
||||
};
|
||||
mockGetContents(dummyResponse);
|
||||
testingUtils.mockGetContents(dummyResponse, 400);
|
||||
|
||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||
setInput('config-file', repoReference);
|
||||
@@ -351,7 +339,8 @@ test("Invalid format of remote config handled correctly", async t => {
|
||||
await configUtils.initConfig();
|
||||
throw new Error('initConfig did not throw error');
|
||||
} catch (err) {
|
||||
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference)));
|
||||
const reason = util.fileDownloadError(repoReference);
|
||||
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference, reason)));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
+11
-20
@@ -399,12 +399,8 @@ export function getConfigFileRepoFormatInvalidMessage(configFile: string): strin
|
||||
return error;
|
||||
}
|
||||
|
||||
export function getConfigFileFormatInvalidMessage(configFile: string): string {
|
||||
return 'The configuration file "' + configFile + '" could not be read';
|
||||
}
|
||||
|
||||
export function getConfigFileDirectoryGivenMessage(configFile: string): string {
|
||||
return 'The configuration file "' + configFile + '" looks like a directory, not a file';
|
||||
export function getConfigFileFormatInvalidMessage(configFile: string, reason: string): string {
|
||||
return 'The configuration file "' + configFile + '" could not be read. Reason: ' + reason;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
if ("content" in response.data && response.data.content !== undefined) {
|
||||
fileContents = response.data.content;
|
||||
} else if (Array.isArray(response.data)) {
|
||||
throw new Error(getConfigFileDirectoryGivenMessage(configFile));
|
||||
} else {
|
||||
throw new Error(getConfigFileFormatInvalidMessage(configFile));
|
||||
try {
|
||||
fileContents = await util.getFileContentsUsingAPI(
|
||||
pieces.groups.owner,
|
||||
pieces.groups.repo,
|
||||
pieces.groups.path,
|
||||
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 sinon from 'sinon';
|
||||
|
||||
import * as api from './api-client';
|
||||
import * as CodeQL from './codeql';
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+7
-26
@@ -1,14 +1,12 @@
|
||||
import * as github from "@actions/github";
|
||||
import test from 'ava';
|
||||
import * as fs from 'fs';
|
||||
import * as os from "os";
|
||||
import sinon from 'sinon';
|
||||
|
||||
import * as api from './api-client';
|
||||
import {setupTests} from './testing-utils';
|
||||
|
||||
import * as testingUtils from './testing-utils';
|
||||
import * as util from './util';
|
||||
|
||||
setupTests(test);
|
||||
testingUtils.setupTests(test);
|
||||
|
||||
test('getToolNames', t => {
|
||||
const input = fs.readFileSync(__dirname + '/../src/testdata/tool-names.sarif', 'utf8');
|
||||
@@ -153,23 +151,9 @@ test('getExtraOptionsEnvParam() fails on invalid JSON', t => {
|
||||
|
||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
||||
});
|
||||
type GetContentsResponse = { content?: string; } | {}[];
|
||||
|
||||
function mockGetContents(content: GetContentsResponse, status: number, isDirectory = false): 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: isDirectory ? [content] : content,
|
||||
status: status
|
||||
};
|
||||
|
||||
const spyGetContents = sinon.stub(client.repos, "getContents").resolves(response as any);
|
||||
sinon.stub(api, "getApiClient").value(() => client);
|
||||
return spyGetContents;
|
||||
}
|
||||
|
||||
test('getFileContentsUsingAPI() throws if the request does not succeed', async t => {
|
||||
const spyGetContents = mockGetContents({}, 400);
|
||||
const spyGetContents = testingUtils.mockGetContents({}, 400);
|
||||
try {
|
||||
await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||
throw new Error('initConfig did not throw error');
|
||||
@@ -180,11 +164,8 @@ test('getFileContentsUsingAPI() throws if the request does not succeed', async t
|
||||
});
|
||||
|
||||
test('getFileContentsUsingAPI() throws if the requested file is a directory', async t => {
|
||||
const inputFileContents = `content content content`;
|
||||
const dummyResponse = {
|
||||
content: Buffer.from(inputFileContents).toString("base64"),
|
||||
};
|
||||
const spyGetContents = mockGetContents(dummyResponse, 200, true);
|
||||
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');
|
||||
@@ -199,7 +180,7 @@ test('getFileContentsUsingAPI() returns the right content', async t => {
|
||||
const dummyResponse = {
|
||||
content: Buffer.from(inputFileContents).toString("base64"),
|
||||
};
|
||||
const spyGetContents = mockGetContents(dummyResponse, 200);
|
||||
const spyGetContents = testingUtils.mockGetContents(dummyResponse, 200);
|
||||
const content = await util.getFileContentsUsingAPI('github', 'codeql-action', 'non-existing-file', 'main');
|
||||
|
||||
t.deepEqual(content, inputFileContents);
|
||||
|
||||
Reference in New Issue
Block a user