Skip to content

Commit 50aaf3b

Browse files
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.
1 parent 847082c commit 50aaf3b

2 files changed

Lines changed: 54 additions & 51 deletions

File tree

extensions/ql-vscode/src/remote-queries/gh-api/gh-api-client.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
VariantAnalysisRepoTask,
77
VariantAnalysisSubmissionRequest
88
} from './variant-analysis';
9+
import { Repository } from './repository';
910

1011
export async function submitVariantAnalysis(
1112
credentials: Credentials,
@@ -73,13 +74,13 @@ export async function getVariantAnalysisRepo(
7374
return response.data;
7475
}
7576

76-
export async function getRepositoryIdFromNwo(
77+
export async function getRepositoryFromNwo(
7778
credentials: Credentials,
7879
owner: string,
7980
repo: string
80-
): Promise<number> {
81+
): Promise<Repository> {
8182
const octokit = await credentials.getOctokit();
8283

8384
const response = await octokit.rest.repos.get({ owner, repo });
84-
return response.data.id;
85+
return response.data as Repository;
8586
}

extensions/ql-vscode/src/remote-queries/run-remote-query.ts

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { getErrorMessage, REPO_REGEX } from '../pure/helpers-pure';
2727
import * as ghApiClient from './gh-api/gh-api-client';
2828
import { getRepositorySelection, isValidSelection, RepositorySelection } from './repository-selection';
2929
import { VariantAnalysisQueryLanguage, VariantAnalysisSubmission } from './shared/variant-analysis';
30+
import { Repository } from './shared/repository';
3031

3132
export interface QlPack {
3233
name: string;
@@ -212,33 +213,7 @@ export async function runRemoteQuery(
212213
message: 'Determining controller repo'
213214
});
214215

215-
// Get the controller repo from the config, if it exists.
216-
// If it doesn't exist, prompt the user to enter it, and save that value to the config.
217-
let controllerRepoNwo: string | undefined;
218-
controllerRepoNwo = getRemoteControllerRepo();
219-
if (!controllerRepoNwo || !REPO_REGEX.test(controllerRepoNwo)) {
220-
void logger.log(controllerRepoNwo ? 'Invalid controller repository name.' : 'No controller repository defined.');
221-
controllerRepoNwo = await window.showInputBox({
222-
title: 'Controller repository in which to run the GitHub Actions workflow for this variant analysis',
223-
placeHolder: '<owner>/<repo>',
224-
prompt: 'Enter the name of a GitHub repository in the format <owner>/<repo>',
225-
ignoreFocusOut: true,
226-
});
227-
if (!controllerRepoNwo) {
228-
void showAndLogErrorMessage('No controller repository entered.');
229-
return;
230-
} else if (!REPO_REGEX.test(controllerRepoNwo)) { // Check if user entered invalid input
231-
void showAndLogErrorMessage('Invalid repository format. Must be a valid GitHub repository in the format <owner>/<repo>.');
232-
return;
233-
}
234-
void logger.log(`Setting the controller repository as: ${controllerRepoNwo}`);
235-
await setRemoteControllerRepo(controllerRepoNwo);
236-
}
237-
238-
void logger.log(`Using controller repository: ${controllerRepoNwo}`);
239-
const [owner, repo] = controllerRepoNwo.split('/');
240-
const controllerRepoId = await getControllerRepoId(credentials, owner, repo);
241-
void logger.log(`Controller repository ID: ${controllerRepoId}`);
216+
const controllerRepo = await getControllerRepo(credentials);
242217

243218
progress({
244219
maxStep: 4,
@@ -271,7 +246,7 @@ export async function runRemoteQuery(
271246
const variantAnalysisSubmission: VariantAnalysisSubmission = {
272247
startTime: queryStartTime,
273248
actionRepoRef: actionBranch,
274-
controllerRepoId: controllerRepoId,
249+
controllerRepoId: controllerRepo.id,
275250
query: {
276251
name: queryName,
277252
filePath: queryFile,
@@ -294,7 +269,7 @@ export async function runRemoteQuery(
294269
return;
295270

296271
} else {
297-
const apiResponse = await runRemoteQueriesApiRequest(credentials, actionBranch, language, repoSelection, owner, repo, base64Pack, dryRun);
272+
const apiResponse = await runRemoteQueriesApiRequest(credentials, actionBranch, language, repoSelection, controllerRepo, base64Pack, dryRun);
298273

299274
if (dryRun) {
300275
return { queryDirPath: remoteQueryDir.path };
@@ -308,8 +283,7 @@ export async function runRemoteQuery(
308283
const remoteQuery = await buildRemoteQueryEntity(
309284
queryFile,
310285
queryMetadata,
311-
owner,
312-
repo,
286+
controllerRepo,
313287
queryStartTime,
314288
workflowRunId,
315289
language,
@@ -335,8 +309,7 @@ async function runRemoteQueriesApiRequest(
335309
ref: string,
336310
language: string,
337311
repoSelection: RepositorySelection,
338-
owner: string,
339-
repo: string,
312+
controllerRepo: Repository,
340313
queryPackBase64: string,
341314
dryRun = false
342315
): Promise<void | QueriesResponse> {
@@ -352,8 +325,7 @@ async function runRemoteQueriesApiRequest(
352325
if (dryRun) {
353326
void showAndLogInformationMessage('[DRY RUN] Would have sent request. See extension log for the payload.');
354327
void logger.log(JSON.stringify({
355-
owner,
356-
repo,
328+
controllerRepo,
357329
data: {
358330
...data,
359331
queryPackBase64: queryPackBase64.substring(0, 100) + '... ' + queryPackBase64.length + ' bytes'
@@ -365,14 +337,13 @@ async function runRemoteQueriesApiRequest(
365337
try {
366338
const octokit = await credentials.getOctokit();
367339
const response: OctokitResponse<QueriesResponse, number> = await octokit.request(
368-
'POST /repos/:owner/:repo/code-scanning/codeql/queries',
340+
'POST /repos/:controllerRepo/code-scanning/codeql/queries',
369341
{
370-
owner,
371-
repo,
342+
controllerRepo: controllerRepo.fullName,
372343
data
373344
}
374345
);
375-
const { popupMessage, logMessage } = parseResponse(owner, repo, response.data);
346+
const { popupMessage, logMessage } = parseResponse(controllerRepo, response.data);
376347
void showAndLogInformationMessage(popupMessage, { fullMessage: logMessage });
377348
return response.data;
378349
} catch (error: any) {
@@ -388,14 +359,14 @@ const eol = os.EOL;
388359
const eol2 = os.EOL + os.EOL;
389360

390361
// exported for testing only
391-
export function parseResponse(owner: string, repo: string, response: QueriesResponse) {
362+
export function parseResponse(controllerRepo: Repository, response: QueriesResponse) {
392363
const repositoriesQueried = response.repositories_queried;
393364
const repositoryCount = repositoriesQueried.length;
394365

395-
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}).`
366+
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}).`
396367
+ (response.errors ? `${eol2}Some repositories could not be scheduled. See extension log for details.` : '');
397368

398-
let logMessage = `Successfully scheduled runs on ${pluralize(repositoryCount, 'repository', 'repositories')}. See https://github.com/${owner}/${repo}/actions/runs/${response.workflow_run_id}.`;
369+
let logMessage = `Successfully scheduled runs on ${pluralize(repositoryCount, 'repository', 'repositories')}. See https://github.com/${controllerRepo.fullName}/actions/runs/${response.workflow_run_id}.`;
399370
logMessage += `${eol2}Repositories queried:${eol}${repositoriesQueried.join(', ')}`;
400371
if (response.errors) {
401372
const { invalid_repositories, repositories_without_database, private_repositories, cutoff_repositories, cutoff_repositories_count } = response.errors;
@@ -459,24 +430,24 @@ async function ensureNameAndSuite(queryPackDir: string, packRelativePath: string
459430
async function buildRemoteQueryEntity(
460431
queryFilePath: string,
461432
queryMetadata: QueryMetadata | undefined,
462-
controllerRepoOwner: string,
463-
controllerRepoName: string,
433+
controllerRepo: Repository,
464434
queryStartTime: number,
465435
workflowRunId: number,
466436
language: string,
467437
repositoryCount: number
468438
): Promise<RemoteQuery> {
469439
const queryName = getQueryName(queryMetadata, queryFilePath);
470440
const queryText = await fs.readFile(queryFilePath, 'utf8');
441+
const [owner, name] = controllerRepo.fullName.split('/');
471442

472443
return {
473444
queryName,
474445
queryFilePath,
475446
queryText,
476447
language,
477448
controllerRepository: {
478-
owner: controllerRepoOwner,
479-
name: controllerRepoName,
449+
owner,
450+
name,
480451
},
481452
executionStartTime: queryStartTime,
482453
actionsWorkflowRunId: workflowRunId,
@@ -489,9 +460,40 @@ function getQueryName(queryMetadata: QueryMetadata | undefined, queryFilePath: s
489460
return queryMetadata?.name ?? path.basename(queryFilePath);
490461
}
491462

492-
async function getControllerRepoId(credentials: Credentials, owner: string, repo: string): Promise<number> {
463+
async function getControllerRepo(credentials: Credentials): Promise<Repository> {
464+
// Get the controller repo from the config, if it exists.
465+
// If it doesn't exist, prompt the user to enter it, and save that value to the config.
466+
let controllerRepoNwo: string | undefined;
467+
controllerRepoNwo = getRemoteControllerRepo();
468+
if (!controllerRepoNwo || !REPO_REGEX.test(controllerRepoNwo)) {
469+
void logger.log(controllerRepoNwo ? 'Invalid controller repository name.' : 'No controller repository defined.');
470+
controllerRepoNwo = await window.showInputBox({
471+
title: 'Controller repository in which to run the GitHub Actions workflow for this variant analysis',
472+
placeHolder: '<owner>/<repo>',
473+
prompt: 'Enter the name of a GitHub repository in the format <owner>/<repo>',
474+
ignoreFocusOut: true,
475+
});
476+
if (!controllerRepoNwo) {
477+
throw new UserCancellationException('No controller repository entered.');
478+
} else if (!REPO_REGEX.test(controllerRepoNwo)) { // Check if user entered invalid input
479+
throw new UserCancellationException('Invalid repository format. Must be a valid GitHub repository in the format <owner>/<repo>.');
480+
}
481+
void logger.log(`Setting the controller repository as: ${controllerRepoNwo}`);
482+
await setRemoteControllerRepo(controllerRepoNwo);
483+
}
484+
485+
void logger.log(`Using controller repository: ${controllerRepoNwo}`);
486+
const [owner, repo] = controllerRepoNwo.split('/');
487+
493488
try {
494-
return await ghApiClient.getRepositoryIdFromNwo(credentials, owner, repo);
489+
const controllerRepo = await ghApiClient.getRepositoryFromNwo(credentials, owner, repo);
490+
void logger.log(`Controller repository ID: ${controllerRepo.id}`);
491+
return {
492+
id: controllerRepo.id,
493+
fullName: controllerRepo.full_name,
494+
private: controllerRepo.private,
495+
};
496+
495497
} catch (e: any) {
496498
if ((e as RequestError).status === 404) {
497499
throw new Error(`Controller repository "${owner}/${repo}" not found`);

0 commit comments

Comments
 (0)