diff --git a/tools/@aws-cdk/prlint/lint.ts b/tools/@aws-cdk/prlint/lint.ts index 48c5a23819459..39cd4db00919c 100644 --- a/tools/@aws-cdk/prlint/lint.ts +++ b/tools/@aws-cdk/prlint/lint.ts @@ -3,6 +3,7 @@ import * as path from 'path'; import { Octokit } from '@octokit/rest'; import { Endpoints } from '@octokit/types'; import { StatusEvent } from '@octokit/webhooks-definitions/schema'; +import type { components } from '@octokit/openapi-types'; import { findModulePath, moduleStability } from './module'; import { breakingModules } from './parser'; @@ -10,6 +11,18 @@ export type GitHubPr = Endpoints['GET /repos/{owner}/{repo}/pulls/{pull_number}']['response']['data']; export const CODE_BUILD_CONTEXT = 'AWS CodeBuild us-east-1 (AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv)'; +export const CODECOV_PREFIX = 'codecov/'; + +export const CODECOV_CHECKS = [ + 'patch', + 'patch/packages/aws-cdk', + 'patch/packages/aws-cdk-lib/core', + 'project', + 'project/packages/aws-cdk', + 'project/packages/aws-cdk-lib/core' +]; + +type CheckRunConclusion = components['schemas']['check-run']['conclusion'] const PR_FROM_MAIN_ERROR = 'Pull requests from `main` branch of a fork cannot be accepted. Please reopen this contribution from another branch on your fork. For more information, see https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md#step-4-pull-request.'; @@ -24,6 +37,7 @@ enum Exemption { CLI_INTEG_TESTED = 'pr-linter/cli-integ-tested', REQUEST_CLARIFICATION = 'pr/reviewer-clarification-requested', REQUEST_EXEMPTION = 'pr-linter/exemption-requested', + CODECOV = "pr-linter/exempt-codecov", } export interface GithubStatusEvent { @@ -352,6 +366,24 @@ export class PullRequestLinter { } } + private async checkRunConclusion(sha: string, checkName: string): Promise { + const response = await this.client.paginate(this.client.checks.listForRef, { + owner: this.prParams.owner, + repo: this.prParams.repo, + ref: sha, + }); + + // grab the last check run that was started + const conclusion = response.check_runs + .filter(c => c.name === checkName) + .filter(c => c.started_at != null) + .sort((c1, c2) => c2.started_at!.localeCompare(c1.started_at!)) + .map(s => s.conclusion)[0]; + + console.log(`${checkName} conclusion: ${conclusion}`) + return conclusion; + } + /** * Assess whether or not a PR is ready for review. * This is needed because some things that we need to evaluate are not filterable on @@ -575,6 +607,25 @@ export class PullRequestLinter { ], }); + const codecovTests: Test[] = []; + for (const c of CODECOV_CHECKS) { + const checkName = `${CODECOV_PREFIX}${c}`; + const status = await this.checkRunConclusion(sha, checkName); + codecovTests.push({ + test: () => { + const result = new TestResult(); + const message = status == null ? `${checkName} has not started yet` : `${checkName} job is in status: ${status}`; + result.assessFailure(status !== 'success', message); + return result; + } + }) + } + + validationCollector.validateRuleSet({ + exemption: shouldExemptCodecov, + testRuleSet: codecovTests, + }); + console.log("Deleting PR Linter Comment now"); await this.deletePRLinterComment(); try { @@ -656,6 +707,10 @@ function fixContainsIntegTest(pr: GitHubPr, files: GitHubFile[]): TestResult { return result; } +function shouldExemptCodecov(pr: GitHubPr): boolean { + return hasLabel(pr, Exemption.CODECOV); +} + function shouldExemptReadme(pr: GitHubPr): boolean { return hasLabel(pr, Exemption.README); } diff --git a/tools/@aws-cdk/prlint/test/lint.test.ts b/tools/@aws-cdk/prlint/test/lint.test.ts index 1de1f3c334ee0..fe64c74d026f6 100644 --- a/tools/@aws-cdk/prlint/test/lint.test.ts +++ b/tools/@aws-cdk/prlint/test/lint.test.ts @@ -1190,6 +1190,18 @@ function configureMock(pr: Subset, prFiles?: linter.GitHubFile[ }, }; + const checksClient = { + listForRef() { + return { + data: { check_runs: linter.CODECOV_CHECKS.map(c => ({ + name: `${linter.CODECOV_PREFIX}${c}`, + conclusion: 'success', + started_at: '1' + }))}, + } + } + } + const searchClient = { issuesAndPullRequests() {}, }; @@ -1204,6 +1216,7 @@ function configureMock(pr: Subset, prFiles?: linter.GitHubFile[ issues: issuesClient as any, search: searchClient as any, repos: reposClient as any, + checks: checksClient as any, paginate: (method: any, args: any) => { return method(args).data; }, } as any, });