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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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`);
|
||||
|
||||
Reference in New Issue
Block a user