Retrieve remote configuration where specified
This commit is contained in:
parent
388403b46e
commit
366d8a32d1
6 changed files with 78 additions and 23 deletions
39
lib/config-utils.js
generated
39
lib/config-utils.js
generated
|
|
@ -6,9 +6,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const io = __importStar(require("@actions/io"));
|
||||
const octokit = __importStar(require("@octokit/rest"));
|
||||
const console_log_level_1 = __importDefault(require("console-log-level"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const path = __importStar(require("path"));
|
||||
|
|
@ -155,7 +160,7 @@ exports.getConfigFileRepoFormatInvalid = getConfigFileRepoFormatInvalid;
|
|||
function getConfigFilePropertyError(configFile, property, error) {
|
||||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||
}
|
||||
function initConfig() {
|
||||
async function initConfig() {
|
||||
let configFile = core.getInput('config-file');
|
||||
const config = new Config();
|
||||
// If no config file was provided create an empty one
|
||||
|
|
@ -171,7 +176,7 @@ function initConfig() {
|
|||
parsedYAML = getLocalConfig(configFile, workspacePath);
|
||||
}
|
||||
else {
|
||||
parsedYAML = getRemoteConfig(configFile);
|
||||
parsedYAML = await getRemoteConfig(configFile);
|
||||
}
|
||||
if (NAME_PROPERTY in parsedYAML) {
|
||||
if (typeof parsedYAML[NAME_PROPERTY] !== "string") {
|
||||
|
|
@ -242,14 +247,32 @@ function getLocalConfig(configFile, workspacePath) {
|
|||
}
|
||||
return yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
|
||||
}
|
||||
function getRemoteConfig(configFile) {
|
||||
// validate the config location
|
||||
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<filepath>[^@]+)@(?<ref>.*)');
|
||||
async function getRemoteConfig(configFile) {
|
||||
// retrieve the various parts of the config location, and ensure they're present
|
||||
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)');
|
||||
const pieces = format.exec(configFile);
|
||||
if (pieces === null || pieces.length < 4) {
|
||||
// 5 = 4 groups + the whole expression
|
||||
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
|
||||
throw new Error(getConfigFileRepoFormatInvalid(configFile));
|
||||
}
|
||||
return []; // temp
|
||||
let ok = new octokit.Octokit({
|
||||
auth: core.getInput('token'),
|
||||
userAgent: "CodeQL Action",
|
||||
log: console_log_level_1.default({ level: "debug" })
|
||||
});
|
||||
const response = await ok.repos.getContents({
|
||||
owner: pieces.groups.owner,
|
||||
repo: pieces.groups.repo,
|
||||
path: pieces.groups.path,
|
||||
ref: pieces.groups.ref,
|
||||
});
|
||||
// TODO handle errors (file not found etc)
|
||||
// todo handle response.encoding not being base64
|
||||
let fileContents;
|
||||
if ("content" in response.data) {
|
||||
fileContents = response.data.content;
|
||||
} // todo handle else case
|
||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
||||
}
|
||||
function getConfigFolder() {
|
||||
return util.getRequiredEnvParam('RUNNER_TEMP');
|
||||
|
|
@ -274,7 +297,7 @@ async function loadConfig() {
|
|||
return JSON.parse(configString);
|
||||
}
|
||||
else {
|
||||
const config = initConfig();
|
||||
const config = await initConfig();
|
||||
core.debug('Initialized config:');
|
||||
core.debug(JSON.stringify(config));
|
||||
await saveConfig(config);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
9
lib/config-utils.test.js
generated
9
lib/config-utils.test.js
generated
|
|
@ -177,14 +177,19 @@ ava_1.default("Octokit used when reading remote config", async (t) => {
|
|||
- b
|
||||
paths:
|
||||
- c/d`;
|
||||
const dummyResponse = [
|
||||
{ data: inputFileContents }
|
||||
];
|
||||
let ok = new octokit.Octokit({
|
||||
userAgent: "CodeQL Action",
|
||||
});
|
||||
const spyRequest = sinon_1.default.stub(ok, "request").resolves(inputFileContents);
|
||||
const repos = ok.repos;
|
||||
const spyGetContents = sinon_1.default.stub(repos, "getContents").resolves(Promise.resolve(dummyResponse));
|
||||
ok.repos = repos;
|
||||
sinon_1.default.stub(octokit, "Octokit").resolves(ok);
|
||||
setInput('config-file', 'octo-org/codeql-config/config.yaml@main');
|
||||
await configUtils.loadConfig();
|
||||
t.assert(spyRequest.called);
|
||||
t.assert(spyGetContents.called);
|
||||
});
|
||||
});
|
||||
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -198,17 +198,21 @@ test("Octokit used when reading remote config", async t => {
|
|||
- b
|
||||
paths:
|
||||
- c/d`;
|
||||
const dummyResponse = [
|
||||
{data: inputFileContents}
|
||||
];
|
||||
|
||||
let ok = new octokit.Octokit({
|
||||
userAgent: "CodeQL Action",
|
||||
});
|
||||
const spyRequest = sinon.stub(ok, "request").resolves(inputFileContents);
|
||||
|
||||
const repos = ok.repos;
|
||||
const spyGetContents = sinon.stub(repos, "getContents").resolves(Promise.resolve(dummyResponse));
|
||||
ok.repos = repos;
|
||||
sinon.stub(octokit, "Octokit").resolves(ok);
|
||||
|
||||
setInput('config-file', 'octo-org/codeql-config/config.yaml@main');
|
||||
await configUtils.loadConfig();
|
||||
t.assert(spyRequest.called);
|
||||
t.assert(spyGetContents.called);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import * as core from '@actions/core';
|
||||
import * as io from '@actions/io';
|
||||
import * as octokit from '@octokit/rest';
|
||||
import consoleLogLevel from 'console-log-level';
|
||||
import * as fs from 'fs';
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as path from 'path';
|
||||
|
|
@ -174,7 +176,7 @@ function getConfigFilePropertyError(configFile: string, property: string, error:
|
|||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||
}
|
||||
|
||||
function initConfig(): Config {
|
||||
async function initConfig(): Promise<Config> {
|
||||
let configFile = core.getInput('config-file');
|
||||
|
||||
const config = new Config();
|
||||
|
|
@ -194,7 +196,7 @@ function initConfig(): Config {
|
|||
|
||||
parsedYAML = getLocalConfig(configFile, workspacePath);
|
||||
} else {
|
||||
parsedYAML = getRemoteConfig(configFile);
|
||||
parsedYAML = await getRemoteConfig(configFile);
|
||||
}
|
||||
|
||||
if (NAME_PROPERTY in parsedYAML) {
|
||||
|
|
@ -276,14 +278,35 @@ function getLocalConfig(configFile: string, workspacePath: string): any {
|
|||
return yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
|
||||
}
|
||||
|
||||
function getRemoteConfig(configFile: string): any {
|
||||
// validate the config location
|
||||
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<filepath>[^@]+)@(?<ref>.*)');
|
||||
async function getRemoteConfig(configFile: string): Promise<any> {
|
||||
// retrieve the various parts of the config location, and ensure they're present
|
||||
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)');
|
||||
const pieces = format.exec(configFile);
|
||||
if (pieces === null || pieces.length < 4) {
|
||||
// 5 = 4 groups + the whole expression
|
||||
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
|
||||
throw new Error(getConfigFileRepoFormatInvalid(configFile));
|
||||
}
|
||||
return []; // temp
|
||||
|
||||
let ok = new octokit.Octokit({
|
||||
auth: core.getInput('token'),
|
||||
userAgent: "CodeQL Action",
|
||||
log: consoleLogLevel({ level: "debug" })
|
||||
});
|
||||
const response = await ok.repos.getContents({
|
||||
owner: pieces.groups.owner,
|
||||
repo: pieces.groups.repo,
|
||||
path: pieces.groups.path,
|
||||
ref: pieces.groups.ref,
|
||||
});
|
||||
|
||||
// TODO handle errors (file not found etc)
|
||||
// todo handle response.encoding not being base64
|
||||
let fileContents;
|
||||
if ("content" in response.data) {
|
||||
fileContents = response.data.content;
|
||||
} // todo handle else case
|
||||
|
||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
||||
}
|
||||
|
||||
function getConfigFolder(): string {
|
||||
|
|
@ -311,7 +334,7 @@ export async function loadConfig(): Promise<Config> {
|
|||
return JSON.parse(configString);
|
||||
|
||||
} else {
|
||||
const config = initConfig();
|
||||
const config = await initConfig();
|
||||
core.debug('Initialized config:');
|
||||
core.debug(JSON.stringify(config));
|
||||
await saveConfig(config);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue