Add validation of remote config location, no retrieval yet
This commit is contained in:
parent
153a598a97
commit
a19d19e0a3
6 changed files with 108 additions and 25 deletions
44
lib/config-utils.js
generated
44
lib/config-utils.js
generated
|
|
@ -146,6 +146,12 @@ function getConfigFileDoesNotExistErrorMessage(configFile) {
|
||||||
return 'The configuration file "' + configFile + '" does not exist';
|
return 'The configuration file "' + configFile + '" does not exist';
|
||||||
}
|
}
|
||||||
exports.getConfigFileDoesNotExistErrorMessage = getConfigFileDoesNotExistErrorMessage;
|
exports.getConfigFileDoesNotExistErrorMessage = getConfigFileDoesNotExistErrorMessage;
|
||||||
|
function getConfigFileRepoFormatInvalid(configFile) {
|
||||||
|
let error = 'The configuration file "' + configFile + '" is not a supported remote file reference.';
|
||||||
|
error += ' Expected format <owner>/<repository>/<file-path>@<ref>';
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
exports.getConfigFileRepoFormatInvalid = getConfigFileRepoFormatInvalid;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
@ -157,18 +163,16 @@ function initConfig() {
|
||||||
core.debug('No configuration file was provided');
|
core.debug('No configuration file was provided');
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
// Treat the config file as relative to the workspace
|
let parsedYAML;
|
||||||
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
|
if (isLocal(configFile)) {
|
||||||
configFile = path.resolve(workspacePath, configFile);
|
// Treat the config file as relative to the workspace
|
||||||
// Error if the config file is now outside of the workspace
|
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
|
||||||
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
configFile = path.resolve(workspacePath, configFile);
|
||||||
throw new Error(getConfigFileOutsideWorkspaceErrorMessage(configFile));
|
parsedYAML = getLocalConfig(configFile, workspacePath);
|
||||||
}
|
}
|
||||||
// Error if the file does not exist
|
else {
|
||||||
if (!fs.existsSync(configFile)) {
|
parsedYAML = getRemoteConfig(configFile);
|
||||||
throw new Error(getConfigFileDoesNotExistErrorMessage(configFile));
|
|
||||||
}
|
}
|
||||||
const parsedYAML = yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
|
|
||||||
if (NAME_PROPERTY in parsedYAML) {
|
if (NAME_PROPERTY in parsedYAML) {
|
||||||
if (typeof parsedYAML[NAME_PROPERTY] !== "string") {
|
if (typeof parsedYAML[NAME_PROPERTY] !== "string") {
|
||||||
throw new Error(getNameInvalid(configFile));
|
throw new Error(getNameInvalid(configFile));
|
||||||
|
|
@ -227,6 +231,26 @@ function isLocal(configPath) {
|
||||||
return (configPath.indexOf("@") === -1);
|
return (configPath.indexOf("@") === -1);
|
||||||
}
|
}
|
||||||
exports.isLocal = isLocal;
|
exports.isLocal = isLocal;
|
||||||
|
function getLocalConfig(configFile, workspacePath) {
|
||||||
|
// Error if the config file is now outside of the workspace
|
||||||
|
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
||||||
|
throw new Error(getConfigFileOutsideWorkspaceErrorMessage(configFile));
|
||||||
|
}
|
||||||
|
// Error if the file does not exist
|
||||||
|
if (!fs.existsSync(configFile)) {
|
||||||
|
throw new Error(getConfigFileDoesNotExistErrorMessage(configFile));
|
||||||
|
}
|
||||||
|
return yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
|
||||||
|
}
|
||||||
|
function getRemoteConfig(configFile) {
|
||||||
|
// validate the config location
|
||||||
|
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<filepath>[^@]+)@(<?ref>.*)');
|
||||||
|
const pieces = format.exec(configFile);
|
||||||
|
if (pieces === null || pieces.length < 4) {
|
||||||
|
throw new Error(getConfigFileRepoFormatInvalid(configFile));
|
||||||
|
}
|
||||||
|
return []; // temp
|
||||||
|
}
|
||||||
function getConfigFolder() {
|
function getConfigFolder() {
|
||||||
return util.getRequiredEnvParam('RUNNER_TEMP');
|
return util.getRequiredEnvParam('RUNNER_TEMP');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
15
lib/config-utils.test.js
generated
15
lib/config-utils.test.js
generated
|
|
@ -67,6 +67,21 @@ ava_1.default("load input outside of workspace", async (t) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
ava_1.default("load non-local input with invalid repo syntax", async (t) => {
|
||||||
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
|
// no filename given, just a repo
|
||||||
|
setInput('config-file', 'octo-org/codeql-config@main');
|
||||||
|
try {
|
||||||
|
await configUtils.loadConfig();
|
||||||
|
throw new Error('loadConfig did not throw error');
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
t.deepEqual(err, new Error(configUtils.getConfigFileRepoFormatInvalid('octo-org/codeql-config@main')));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
ava_1.default("load non-existent input", async (t) => {
|
ava_1.default("load non-existent input", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
process.env['RUNNER_TEMP'] = tmpDir;
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -69,6 +69,23 @@ test("load input outside of workspace", async t => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("load non-local input with invalid repo syntax", async t => {
|
||||||
|
return await util.withTmpDir(async tmpDir => {
|
||||||
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
|
|
||||||
|
// no filename given, just a repo
|
||||||
|
setInput('config-file', 'octo-org/codeql-config@main');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await configUtils.loadConfig();
|
||||||
|
throw new Error('loadConfig did not throw error');
|
||||||
|
} catch (err) {
|
||||||
|
t.deepEqual(err, new Error(configUtils.getConfigFileRepoFormatInvalid('octo-org/codeql-config@main')));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("load non-existent input", async t => {
|
test("load non-existent input", async t => {
|
||||||
return await util.withTmpDir(async tmpDir => {
|
return await util.withTmpDir(async tmpDir => {
|
||||||
process.env['RUNNER_TEMP'] = tmpDir;
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,13 @@ export function getConfigFileDoesNotExistErrorMessage(configFile: string): strin
|
||||||
return 'The configuration file "' + configFile + '" does not exist';
|
return 'The configuration file "' + configFile + '" does not exist';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getConfigFileRepoFormatInvalid(configFile: string): string {
|
||||||
|
let error = 'The configuration file "' + configFile + '" is not a supported remote file reference.';
|
||||||
|
error += ' Expected format <owner>/<repository>/<file-path>@<ref>';
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
function getConfigFilePropertyError(configFile: string, property: string, error: string): string {
|
function getConfigFilePropertyError(configFile: string, property: string, error: string): string {
|
||||||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||||
}
|
}
|
||||||
|
|
@ -178,22 +185,18 @@ function initConfig(): Config {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Treat the config file as relative to the workspace
|
let parsedYAML;
|
||||||
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
|
|
||||||
configFile = path.resolve(workspacePath, configFile);
|
|
||||||
|
|
||||||
// Error if the config file is now outside of the workspace
|
if (isLocal(configFile)) {
|
||||||
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
// Treat the config file as relative to the workspace
|
||||||
throw new Error(getConfigFileOutsideWorkspaceErrorMessage(configFile));
|
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
|
||||||
|
configFile = path.resolve(workspacePath, configFile);
|
||||||
|
|
||||||
|
parsedYAML = getLocalConfig(configFile, workspacePath);
|
||||||
|
} else {
|
||||||
|
parsedYAML = getRemoteConfig(configFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error if the file does not exist
|
|
||||||
if (!fs.existsSync(configFile)) {
|
|
||||||
throw new Error(getConfigFileDoesNotExistErrorMessage(configFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsedYAML = yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
|
|
||||||
|
|
||||||
if (NAME_PROPERTY in parsedYAML) {
|
if (NAME_PROPERTY in parsedYAML) {
|
||||||
if (typeof parsedYAML[NAME_PROPERTY] !== "string") {
|
if (typeof parsedYAML[NAME_PROPERTY] !== "string") {
|
||||||
throw new Error(getNameInvalid(configFile));
|
throw new Error(getNameInvalid(configFile));
|
||||||
|
|
@ -259,6 +262,30 @@ export function isLocal(configPath: string): boolean {
|
||||||
return (configPath.indexOf("@") === -1);
|
return (configPath.indexOf("@") === -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLocalConfig(configFile: string, workspacePath: string): any {
|
||||||
|
// Error if the config file is now outside of the workspace
|
||||||
|
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
||||||
|
throw new Error(getConfigFileOutsideWorkspaceErrorMessage(configFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error if the file does not exist
|
||||||
|
if (!fs.existsSync(configFile)) {
|
||||||
|
throw new Error(getConfigFileDoesNotExistErrorMessage(configFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
return yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRemoteConfig(configFile: string): any {
|
||||||
|
// validate the config location
|
||||||
|
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<filepath>[^@]+)@(<?ref>.*)');
|
||||||
|
const pieces = format.exec(configFile);
|
||||||
|
if (pieces === null || pieces.length < 4) {
|
||||||
|
throw new Error(getConfigFileRepoFormatInvalid(configFile));
|
||||||
|
}
|
||||||
|
return []; // temp
|
||||||
|
}
|
||||||
|
|
||||||
function getConfigFolder(): string {
|
function getConfigFolder(): string {
|
||||||
return util.getRequiredEnvParam('RUNNER_TEMP');
|
return util.getRequiredEnvParam('RUNNER_TEMP');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue