Make remote config retrieval more robust
This commit is contained in:
parent
51becd2cf8
commit
0607771cc2
6 changed files with 149 additions and 9 deletions
19
lib/config-utils.js
generated
19
lib/config-utils.js
generated
|
|
@ -153,6 +153,14 @@ function getConfigFileRepoFormatInvalidMessage(configFile) {
|
|||
return error;
|
||||
}
|
||||
exports.getConfigFileRepoFormatInvalidMessage = getConfigFileRepoFormatInvalidMessage;
|
||||
function getConfigFileFormatInvalidMessage(configFile) {
|
||||
return 'The configuration file "' + configFile + '" could not be read';
|
||||
}
|
||||
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) {
|
||||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||
}
|
||||
|
|
@ -256,11 +264,16 @@ async function getRemoteConfig(configFile) {
|
|||
path: pieces.groups.path,
|
||||
ref: pieces.groups.ref,
|
||||
});
|
||||
// todo handle response.encoding not being base64
|
||||
let fileContents;
|
||||
if ("content" in response.data) {
|
||||
if ("content" in response.data && response.data.content !== undefined) {
|
||||
fileContents = response.data.content;
|
||||
} // todo handle else case
|
||||
}
|
||||
else if (Array.isArray(response.data)) {
|
||||
throw new Error(getConfigFileDirectoryGivenMessage(configFile));
|
||||
}
|
||||
else {
|
||||
throw new Error(getConfigFileFormatInvalidMessage(configFile));
|
||||
}
|
||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
||||
}
|
||||
function getConfigFolder() {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
54
lib/config-utils.test.js
generated
54
lib/config-utils.test.js
generated
|
|
@ -164,6 +164,60 @@ ava_1.default("API client used when reading remote config", async (t) => {
|
|||
sinon_1.default.restore();
|
||||
});
|
||||
});
|
||||
ava_1.default("Remote config handles the case where a directory is provided", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||
const dummyResponse = {
|
||||
data: [],
|
||||
};
|
||||
let ok = new octokit.Octokit({
|
||||
userAgent: "CodeQL Action",
|
||||
});
|
||||
const repos = ok.repos;
|
||||
sinon_1.default.stub(repos, "getContents").resolves(Promise.resolve(dummyResponse));
|
||||
ok.repos = repos;
|
||||
sinon_1.default.stub(api, "client").value(ok);
|
||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||
setInput('config-file', repoReference);
|
||||
try {
|
||||
await configUtils.loadConfig();
|
||||
throw new Error('loadConfig did not throw error');
|
||||
}
|
||||
catch (err) {
|
||||
t.deepEqual(err, new Error(configUtils.getConfigFileDirectoryGivenMessage(repoReference)));
|
||||
}
|
||||
sinon_1.default.restore();
|
||||
});
|
||||
});
|
||||
ava_1.default("Invalid format of remote config handled correctly", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||
const dummyResponse = {
|
||||
data: {
|
||||
// note no "content" property here
|
||||
}
|
||||
};
|
||||
let ok = new octokit.Octokit({
|
||||
userAgent: "CodeQL Action",
|
||||
});
|
||||
const repos = ok.repos;
|
||||
sinon_1.default.stub(repos, "getContents").resolves(Promise.resolve(dummyResponse));
|
||||
ok.repos = repos;
|
||||
sinon_1.default.stub(api, "client").value(ok);
|
||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||
setInput('config-file', repoReference);
|
||||
try {
|
||||
await configUtils.loadConfig();
|
||||
throw new Error('loadConfig did not throw error');
|
||||
}
|
||||
catch (err) {
|
||||
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference)));
|
||||
}
|
||||
sinon_1.default.restore();
|
||||
});
|
||||
});
|
||||
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
|
||||
ava_1.default("load invalid input - " + testName, async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -182,6 +182,68 @@ test("API client used when reading remote config", async t => {
|
|||
});
|
||||
});
|
||||
|
||||
test("Remote config handles the case where a directory is provided", async t => {
|
||||
return await util.withTmpDir(async tmpDir => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||
|
||||
const dummyResponse = {
|
||||
data: [], // directories are returned as arrays
|
||||
};
|
||||
|
||||
let ok = new octokit.Octokit({
|
||||
userAgent: "CodeQL Action",
|
||||
});
|
||||
const repos = ok.repos;
|
||||
sinon.stub(repos, "getContents").resolves(Promise.resolve(dummyResponse));
|
||||
ok.repos = repos;
|
||||
sinon.stub(api, "client").value(ok);
|
||||
|
||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||
setInput('config-file', repoReference);
|
||||
try {
|
||||
await configUtils.loadConfig();
|
||||
throw new Error('loadConfig did not throw error');
|
||||
} catch (err) {
|
||||
t.deepEqual(err, new Error(configUtils.getConfigFileDirectoryGivenMessage(repoReference)));
|
||||
}
|
||||
|
||||
sinon.restore();
|
||||
});
|
||||
});
|
||||
|
||||
test("Invalid format of remote config handled correctly", async t => {
|
||||
return await util.withTmpDir(async tmpDir => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||
|
||||
const dummyResponse = {
|
||||
data: {
|
||||
// note no "content" property here
|
||||
}
|
||||
};
|
||||
|
||||
let ok = new octokit.Octokit({
|
||||
userAgent: "CodeQL Action",
|
||||
});
|
||||
const repos = ok.repos;
|
||||
sinon.stub(repos, "getContents").resolves(Promise.resolve(dummyResponse));
|
||||
ok.repos = repos;
|
||||
sinon.stub(api, "client").value(ok);
|
||||
|
||||
const repoReference = 'octo-org/codeql-config/config.yaml@main';
|
||||
setInput('config-file', repoReference);
|
||||
try {
|
||||
await configUtils.loadConfig();
|
||||
throw new Error('loadConfig did not throw error');
|
||||
} catch (err) {
|
||||
t.deepEqual(err, new Error(configUtils.getConfigFileFormatInvalidMessage(repoReference)));
|
||||
}
|
||||
|
||||
sinon.restore();
|
||||
});
|
||||
});
|
||||
|
||||
function doInvalidInputTest(
|
||||
testName: string,
|
||||
inputFileContents: string,
|
||||
|
|
|
|||
|
|
@ -171,6 +171,14 @@ 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';
|
||||
}
|
||||
|
||||
function getConfigFilePropertyError(configFile: string, property: string, error: string): string {
|
||||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||
}
|
||||
|
|
@ -293,11 +301,14 @@ async function getRemoteConfig(configFile: string): Promise<any> {
|
|||
ref: pieces.groups.ref,
|
||||
});
|
||||
|
||||
// todo handle response.encoding not being base64
|
||||
let fileContents;
|
||||
if ("content" in response.data) {
|
||||
let fileContents: string;
|
||||
if ("content" in response.data && response.data.content !== undefined) {
|
||||
fileContents = response.data.content;
|
||||
} // todo handle else case
|
||||
} else if (Array.isArray(response.data)) {
|
||||
throw new Error(getConfigFileDirectoryGivenMessage(configFile));
|
||||
} else {
|
||||
throw new Error(getConfigFileFormatInvalidMessage(configFile));
|
||||
}
|
||||
|
||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue