Move more implementation of fetching the controller repo into getControllerRepo

This involved changing a few different methods to take a Repository object
instead of taking owner and repo separately. Overall I think this is a good change.
This commit is contained in:
Robert
2022-09-23 11:01:25 +01:00
parent 847082cd30
commit 50aaf3b537
2 changed files with 54 additions and 51 deletions

View File

@@ -6,6 +6,7 @@ import {
VariantAnalysisRepoTask,
VariantAnalysisSubmissionRequest
} from './variant-analysis';
import { Repository } from './repository';
export async function submitVariantAnalysis(
credentials: Credentials,
@@ -73,13 +74,13 @@ export async function getVariantAnalysisRepo(
return response.data;
}
export async function getRepositoryIdFromNwo(
export async function getRepositoryFromNwo(
credentials: Credentials,
owner: string,
repo: string
): Promise<number> {
): Promise<Repository> {
const octokit = await credentials.getOctokit();
const response = await octokit.rest.repos.get({ owner, repo });
return response.data.id;
return response.data as Repository;
}

View File

@@ -27,6 +27,7 @@ import { getErrorMessage, REPO_REGEX } from '../pure/helpers-pure';
import * as ghApiClient from './gh-api/gh-api-client';
import { getRepositorySelection, isValidSelection, RepositorySelection } from './repository-selection';
import { VariantAnalysisQueryLanguage, VariantAnalysisSubmission } from './shared/variant-analysis';
import { Repository } from './shared/repository';
export interface QlPack {
name: string;
@@ -212,33 +213,7 @@ export async function runRemoteQuery(
message: 'Determining controller repo'
});
// Get the controller repo from the config, if it exists.
// If it doesn't exist, prompt the user to enter it, and save that value to the config.
let controllerRepoNwo: string | undefined;
controllerRepoNwo = getRemoteControllerRepo();
if (!controllerRepoNwo || !REPO_REGEX.test(controllerRepoNwo)) {
void logger.log(controllerRepoNwo ? 'Invalid controller repository name.' : 'No controller repository defined.');
controllerRepoNwo = await window.showInputBox({
title: 'Controller repository in which to run the GitHub Actions workflow for this variant analysis',
placeHolder: '<owner>/<repo>',
prompt: 'Enter the name of a GitHub repository in the format <owner>/<repo>',
ignoreFocusOut: true,
});
if (!controllerRepoNwo) {
void showAndLogErrorMessage('No controller repository entered.');
return;
} else if (!REPO_REGEX.test(controllerRepoNwo)) { // Check if user entered invalid input
void showAndLogErrorMessage('Invalid repository format. Must be a valid GitHub repository in the format <owner>/<repo>.');
return;
}
void logger.log(`Setting the controller repository as: ${controllerRepoNwo}`);
await setRemoteControllerRepo(controllerRepoNwo);
}
void logger.log(`Using controller repository: ${controllerRepoNwo}`);
const [owner, repo] = controllerRepoNwo.split('/');
const controllerRepoId = await getControllerRepoId(credentials, owner, repo);
void logger.log(`Controller repository ID: ${controllerRepoId}`);
const controllerRepo = await getControllerRepo(credentials);
progress({
maxStep: 4,
@@ -271,7 +246,7 @@ export async function runRemoteQuery(
const variantAnalysisSubmission: VariantAnalysisSubmission = {
startTime: queryStartTime,
actionRepoRef: actionBranch,
controllerRepoId: controllerRepoId,
controllerRepoId: controllerRepo.id,
query: {
name: queryName,
filePath: queryFile,
@@ -294,7 +269,7 @@ export async function runRemoteQuery(
return;
} else {
const apiResponse = await runRemoteQueriesApiRequest(credentials, actionBranch, language, repoSelection, owner, repo, base64Pack, dryRun);
const apiResponse = await runRemoteQueriesApiRequest(credentials, actionBranch, language, repoSelection, controllerRepo, base64Pack, dryRun);
if (dryRun) {
return { queryDirPath: remoteQueryDir.path };
@@ -308,8 +283,7 @@ export async function runRemoteQuery(
const remoteQuery = await buildRemoteQueryEntity(
queryFile,
queryMetadata,
owner,
repo,
controllerRepo,
queryStartTime,
workflowRunId,
language,
@@ -335,8 +309,7 @@ async function runRemoteQueriesApiRequest(
ref: string,
language: string,
repoSelection: RepositorySelection,
owner: string,
repo: string,
controllerRepo: Repository,
queryPackBase64: string,
dryRun = false
): Promise<void | QueriesResponse> {
@@ -352,8 +325,7 @@ async function runRemoteQueriesApiRequest(
if (dryRun) {
void showAndLogInformationMessage('[DRY RUN] Would have sent request. See extension log for the payload.');
void logger.log(JSON.stringify({
owner,
repo,
controllerRepo,
data: {
...data,
queryPackBase64: queryPackBase64.substring(0, 100) + '... ' + queryPackBase64.length + ' bytes'
@@ -365,14 +337,13 @@ async function runRemoteQueriesApiRequest(
try {
const octokit = await credentials.getOctokit();
const response: OctokitResponse<QueriesResponse, number> = await octokit.request(
'POST /repos/:owner/:repo/code-scanning/codeql/queries',
'POST /repos/:controllerRepo/code-scanning/codeql/queries',
{
owner,
repo,
controllerRepo: controllerRepo.fullName,
data
}
);
const { popupMessage, logMessage } = parseResponse(owner, repo, response.data);
const { popupMessage, logMessage } = parseResponse(controllerRepo, response.data);
void showAndLogInformationMessage(popupMessage, { fullMessage: logMessage });
return response.data;
} catch (error: any) {
@@ -388,14 +359,14 @@ const eol = os.EOL;
const eol2 = os.EOL + os.EOL;
// exported for testing only
export function parseResponse(owner: string, repo: string, response: QueriesResponse) {
export function parseResponse(controllerRepo: Repository, response: QueriesResponse) {
const repositoriesQueried = response.repositories_queried;
const repositoryCount = repositoriesQueried.length;
const popupMessage = `Successfully scheduled runs on ${pluralize(repositoryCount, 'repository', 'repositories')}. [Click here to see the progress](https://github.com/${owner}/${repo}/actions/runs/${response.workflow_run_id}).`
const popupMessage = `Successfully scheduled runs on ${pluralize(repositoryCount, 'repository', 'repositories')}. [Click here to see the progress](https://github.com/${controllerRepo.fullName}/actions/runs/${response.workflow_run_id}).`
+ (response.errors ? `${eol2}Some repositories could not be scheduled. See extension log for details.` : '');
let logMessage = `Successfully scheduled runs on ${pluralize(repositoryCount, 'repository', 'repositories')}. See https://github.com/${owner}/${repo}/actions/runs/${response.workflow_run_id}.`;
let logMessage = `Successfully scheduled runs on ${pluralize(repositoryCount, 'repository', 'repositories')}. See https://github.com/${controllerRepo.fullName}/actions/runs/${response.workflow_run_id}.`;
logMessage += `${eol2}Repositories queried:${eol}${repositoriesQueried.join(', ')}`;
if (response.errors) {
const { invalid_repositories, repositories_without_database, private_repositories, cutoff_repositories, cutoff_repositories_count } = response.errors;
@@ -459,8 +430,7 @@ async function ensureNameAndSuite(queryPackDir: string, packRelativePath: string
async function buildRemoteQueryEntity(
queryFilePath: string,
queryMetadata: QueryMetadata | undefined,
controllerRepoOwner: string,
controllerRepoName: string,
controllerRepo: Repository,
queryStartTime: number,
workflowRunId: number,
language: string,
@@ -468,6 +438,7 @@ async function buildRemoteQueryEntity(
): Promise<RemoteQuery> {
const queryName = getQueryName(queryMetadata, queryFilePath);
const queryText = await fs.readFile(queryFilePath, 'utf8');
const [owner, name] = controllerRepo.fullName.split('/');
return {
queryName,
@@ -475,8 +446,8 @@ async function buildRemoteQueryEntity(
queryText,
language,
controllerRepository: {
owner: controllerRepoOwner,
name: controllerRepoName,
owner,
name,
},
executionStartTime: queryStartTime,
actionsWorkflowRunId: workflowRunId,
@@ -489,9 +460,40 @@ function getQueryName(queryMetadata: QueryMetadata | undefined, queryFilePath: s
return queryMetadata?.name ?? path.basename(queryFilePath);
}
async function getControllerRepoId(credentials: Credentials, owner: string, repo: string): Promise<number> {
async function getControllerRepo(credentials: Credentials): Promise<Repository> {
// Get the controller repo from the config, if it exists.
// If it doesn't exist, prompt the user to enter it, and save that value to the config.
let controllerRepoNwo: string | undefined;
controllerRepoNwo = getRemoteControllerRepo();
if (!controllerRepoNwo || !REPO_REGEX.test(controllerRepoNwo)) {
void logger.log(controllerRepoNwo ? 'Invalid controller repository name.' : 'No controller repository defined.');
controllerRepoNwo = await window.showInputBox({
title: 'Controller repository in which to run the GitHub Actions workflow for this variant analysis',
placeHolder: '<owner>/<repo>',
prompt: 'Enter the name of a GitHub repository in the format <owner>/<repo>',
ignoreFocusOut: true,
});
if (!controllerRepoNwo) {
throw new UserCancellationException('No controller repository entered.');
} else if (!REPO_REGEX.test(controllerRepoNwo)) { // Check if user entered invalid input
throw new UserCancellationException('Invalid repository format. Must be a valid GitHub repository in the format <owner>/<repo>.');
}
void logger.log(`Setting the controller repository as: ${controllerRepoNwo}`);
await setRemoteControllerRepo(controllerRepoNwo);
}
void logger.log(`Using controller repository: ${controllerRepoNwo}`);
const [owner, repo] = controllerRepoNwo.split('/');
try {
return await ghApiClient.getRepositoryIdFromNwo(credentials, owner, repo);
const controllerRepo = await ghApiClient.getRepositoryFromNwo(credentials, owner, repo);
void logger.log(`Controller repository ID: ${controllerRepo.id}`);
return {
id: controllerRepo.id,
fullName: controllerRepo.full_name,
private: controllerRepo.private,
};
} catch (e: any) {
if ((e as RequestError).status === 404) {
throw new Error(`Controller repository "${owner}/${repo}" not found`);