diff --git a/src/operations/backport-to-location.ts b/src/operations/backport-to-location.ts index 0a562b2..5ce1eeb 100644 --- a/src/operations/backport-to-location.ts +++ b/src/operations/backport-to-location.ts @@ -1,10 +1,41 @@ +import { CHECK_PREFIX } from '../constants'; import { PRStatus, BackportPurpose, LogLevel } from '../enums'; +import { getCheckRun } from '../utils/checks-util'; import * as labelUtils from '../utils/label-utils'; import { log } from '../utils/log-util'; import { backportImpl } from '../utils'; import { Probot } from 'probot'; import { SimpleWebHookRepoContext, WebHookPR } from '../types'; +const createOrUpdateCheckRun = async ( + context: SimpleWebHookRepoContext, + pr: WebHookPR, + targetBranch: string, +) => { + const check = await getCheckRun(context, pr, targetBranch); + + if (check) { + if (check.conclusion === 'neutral') { + await context.octokit.checks.update( + context.repo({ + name: check.name, + check_run_id: check.id, + status: 'queued' as 'queued', + }), + ); + } + } else { + await context.octokit.checks.create( + context.repo({ + name: `${CHECK_PREFIX}${targetBranch}`, + head_sha: pr.head.sha, + status: 'queued' as 'queued', + details_url: 'https://github.com/electron/trop', + }), + ); + } +}; + /** * Performs a backport to a specified label representing a branch. * @@ -43,6 +74,8 @@ export const backportToLabel = async ( return; } + await createOrUpdateCheckRun(context, pr, targetBranch); + const labelToRemove = label.name; const labelToAdd = label.name.replace(PRStatus.TARGET, PRStatus.IN_FLIGHT); await backportImpl( @@ -75,6 +108,8 @@ export const backportToBranch = async ( `Executing backport to branch '${targetBranch}'`, ); + await createOrUpdateCheckRun(context, pr, targetBranch); + const labelToRemove = undefined; const labelToAdd = PRStatus.IN_FLIGHT + targetBranch; await backportImpl( diff --git a/src/utils.ts b/src/utils.ts index d3e9756..eb9c22e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,7 +5,6 @@ import simpleGit from 'simple-git'; import queue from './Queue'; import { - CHECK_PREFIX, BACKPORT_REQUESTED_LABEL, DEFAULT_BACKPORT_REVIEW_TEAM, BACKPORT_LABEL, @@ -18,6 +17,7 @@ import { setupRemotes } from './operations/setup-remotes'; import { backportCommitsToBranch } from './operations/backport-commits'; import { getRepoToken } from './utils/token-util'; import { getSupportedBranches, getBackportPattern } from './utils/branch-util'; +import { getCheckRun } from './utils/checks-util'; import { getEnvVar } from './utils/env-util'; import { log } from './utils/log-util'; import { TryBackportOptions } from './interfaces'; @@ -464,36 +464,21 @@ export const backportImpl = async ( const bp = `backport from PR #${pr.number} to "${targetBranch}"`; log('backportImpl', LogLevel.INFO, `Queuing ${bp} for "${slug}"`); - const getCheckRun = async () => { - const allChecks = await context.octokit.checks.listForRef( - context.repo({ - ref: pr.head.sha, - per_page: 100, - }), - ); - - return allChecks.data.check_runs.find((run) => { - return run.name === `${CHECK_PREFIX}${targetBranch}`; - }); - }; - let createdDir: string | null = null; queue.enterQueue( `backport-${pr.head.sha}-${targetBranch}-${purpose}`, async () => { log('backportImpl', LogLevel.INFO, `Executing ${bp} for "${slug}"`); - if (purpose === BackportPurpose.Check) { - const checkRun = await getCheckRun(); - if (checkRun) { - await context.octokit.checks.update( - context.repo({ - check_run_id: checkRun.id, - name: checkRun.name, - status: 'in_progress' as 'in_progress', - }), - ); - } + const checkRun = await getCheckRun(context, pr, targetBranch); + if (checkRun) { + await context.octokit.checks.update( + context.repo({ + check_run_id: checkRun.id, + name: checkRun.name, + status: 'in_progress' as 'in_progress', + }), + ); } const repoAccessToken = await getRepoToken(robot, context); @@ -679,22 +664,19 @@ export const backportImpl = async ( log('backportImpl', LogLevel.INFO, 'Backport process complete'); } - if (purpose === BackportPurpose.Check) { - const checkRun = await getCheckRun(); - if (checkRun) { - context.octokit.checks.update( - context.repo({ - check_run_id: checkRun.id, - name: checkRun.name, - conclusion: 'success' as 'success', - completed_at: new Date().toISOString(), - output: { - title: 'Clean Backport', - summary: `This PR was checked and can be backported to "${targetBranch}" cleanly.`, - }, - }), - ); - } + if (checkRun) { + context.octokit.checks.update( + context.repo({ + check_run_id: checkRun.id, + name: checkRun.name, + conclusion: 'success' as 'success', + completed_at: new Date().toISOString(), + output: { + title: 'Clean Backport', + summary: `This PR was checked and can be backported to "${targetBranch}" cleanly.`, + }, + }), + ); } await fs.remove(createdDir); @@ -762,31 +744,29 @@ export const backportImpl = async ( ]); } - if (purpose === BackportPurpose.Check) { - const checkRun = await getCheckRun(); - if (checkRun) { - const mdSep = '``````````````````````````````'; - const updateOpts = context.repo({ - check_run_id: checkRun.id, - name: checkRun.name, - conclusion: 'neutral' as 'neutral', - completed_at: new Date().toISOString(), - output: { - title: 'Backport Failed', - summary: `This PR was checked and could not be automatically backported to "${targetBranch}" cleanly`, - text: diff - ? `Failed Diff:\n\n${mdSep}diff\n${rawDiff}\n${mdSep}` - : undefined, - annotations: annotations ? annotations : undefined, - }, - }); - try { - await context.octokit.checks.update(updateOpts); - } catch (err) { - // A GitHub error occurred - try to mark it as a failure without annotations. - updateOpts.output!.annotations = undefined; - await context.octokit.checks.update(updateOpts); - } + const checkRun = await getCheckRun(context, pr, targetBranch); + if (checkRun) { + const mdSep = '``````````````````````````````'; + const updateOpts = context.repo({ + check_run_id: checkRun.id, + name: checkRun.name, + conclusion: 'neutral' as 'neutral', + completed_at: new Date().toISOString(), + output: { + title: 'Backport Failed', + summary: `This PR was checked and could not be automatically backported to "${targetBranch}" cleanly`, + text: diff + ? `Failed Diff:\n\n${mdSep}diff\n${rawDiff}\n${mdSep}` + : undefined, + annotations: annotations ? annotations : undefined, + }, + }); + try { + await context.octokit.checks.update(updateOpts); + } catch (err) { + // A GitHub error occurred - try to mark it as a failure without annotations. + updateOpts.output!.annotations = undefined; + await context.octokit.checks.update(updateOpts); } } }, diff --git a/src/utils/checks-util.ts b/src/utils/checks-util.ts index 5ce11f9..710cda1 100644 --- a/src/utils/checks-util.ts +++ b/src/utils/checks-util.ts @@ -1,6 +1,10 @@ import { CheckRunStatus } from '../enums'; -import { BACKPORT_INFORMATION_CHECK } from '../constants'; -import { WebHookPRContext } from '../types'; +import { BACKPORT_INFORMATION_CHECK, CHECK_PREFIX } from '../constants'; +import { + SimpleWebHookRepoContext, + WebHookPR, + WebHookPRContext, +} from '../types'; export async function updateBackportValidityCheck( context: WebHookPRContext, @@ -88,3 +92,20 @@ export async function queueBackportInformationCheck(context: WebHookPRContext) { }), ); } + +export async function getCheckRun( + context: SimpleWebHookRepoContext, + pr: WebHookPR, + targetBranch: string, +) { + const allChecks = await context.octokit.checks.listForRef( + context.repo({ + ref: pr.head.sha, + per_page: 100, + }), + ); + + return allChecks.data.check_runs.find((run) => { + return run.name === `${CHECK_PREFIX}${targetBranch}`; + }); +}