From 7f8eeb3da9bbeab9e83d7847c6b4bf1df5b2ece7 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Mon, 24 Jul 2023 17:07:08 -0400 Subject: [PATCH] chore(prlint): core PRs are always `pr/needs-maintainer-review` (#26487) Built the PR off of #26486 to hopefully avoid merge conflicts if we merge the other first ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- tools/@aws-cdk/prlint/.eslintrc.js | 9 + tools/@aws-cdk/prlint/.gitignore | 1 + tools/@aws-cdk/prlint/index.ts | 4 +- tools/@aws-cdk/prlint/lint.ts | 82 ++++---- tools/@aws-cdk/prlint/module.ts | 8 +- tools/@aws-cdk/prlint/package.json | 10 +- tools/@aws-cdk/prlint/test/lint.test.ts | 222 +++++++++++----------- tools/@aws-cdk/prlint/test/module.test.ts | 4 +- 8 files changed, 180 insertions(+), 160 deletions(-) create mode 100644 tools/@aws-cdk/prlint/.eslintrc.js diff --git a/tools/@aws-cdk/prlint/.eslintrc.js b/tools/@aws-cdk/prlint/.eslintrc.js new file mode 100644 index 0000000000000..7980a8cf2c862 --- /dev/null +++ b/tools/@aws-cdk/prlint/.eslintrc.js @@ -0,0 +1,9 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = { + ...baseConfig, + rules: { + 'no-console': 'off', + 'jest/valid-expect': 'off', + }, +}; diff --git a/tools/@aws-cdk/prlint/.gitignore b/tools/@aws-cdk/prlint/.gitignore index 5801cd7fb289f..53945a9b6c8a0 100644 --- a/tools/@aws-cdk/prlint/.gitignore +++ b/tools/@aws-cdk/prlint/.gitignore @@ -2,3 +2,4 @@ *.js !decs.d.ts +!.eslintrc.js \ No newline at end of file diff --git a/tools/@aws-cdk/prlint/index.ts b/tools/@aws-cdk/prlint/index.ts index 5c2b55af1c5d5..119c056b09070 100644 --- a/tools/@aws-cdk/prlint/index.ts +++ b/tools/@aws-cdk/prlint/index.ts @@ -1,8 +1,8 @@ import * as core from '@actions/core'; import * as github from '@actions/github'; import { Octokit } from '@octokit/rest'; -import * as linter from './lint'; import { StatusEvent, PullRequestEvent } from '@octokit/webhooks-definitions/schema'; +import * as linter from './lint'; async function run() { const token: string = process.env.GITHUB_TOKEN!; @@ -39,4 +39,4 @@ async function run() { } } -run() +void run(); diff --git a/tools/@aws-cdk/prlint/lint.ts b/tools/@aws-cdk/prlint/lint.ts index ae68360d55f1e..f0648ded94785 100644 --- a/tools/@aws-cdk/prlint/lint.ts +++ b/tools/@aws-cdk/prlint/lint.ts @@ -1,13 +1,13 @@ +import { execSync } from 'child_process'; import * as path from 'path'; import { Octokit } from '@octokit/rest'; +import { Endpoints } from '@octokit/types'; import { StatusEvent } from '@octokit/webhooks-definitions/schema'; -import { breakingModules } from './parser'; import { findModulePath, moduleStability } from './module'; -import { Endpoints } from "@octokit/types"; -import { execSync } from 'child_process'; +import { breakingModules } from './parser'; export type GitHubPr = - Endpoints["GET /repos/{owner}/{repo}/pulls/{pull_number}"]["response"]["data"]; + Endpoints['GET /repos/{owner}/{repo}/pulls/{pull_number}']['response']['data']; export const CODE_BUILD_CONTEXT = 'AWS CodeBuild us-east-1 (AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv)'; @@ -237,8 +237,8 @@ export class PullRequestLinter { await this.client.pulls.dismissReview({ ...this.prParams, review_id: existingReview.id, - message: '✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.' - }) + message: '✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.', + }); } } @@ -258,15 +258,15 @@ export class PullRequestLinter { body: 'The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons.' + ' If you believe this pull request should receive an exemption, please comment and provide a justification.' + '\n\n\nA comment requesting an exemption should contain the text `Exemption Request`.' - + ' Additionally, if clarification is needed add `Clarification Request` to a comment.', + + ' Additionally, if clarification is needed add `Clarification Request` to a comment.', event: 'REQUEST_CHANGES', - }) + }); } await this.client.issues.createComment({ ...this.issueParams, body, - }) + }); throw new LinterError(body); } @@ -296,7 +296,7 @@ export class PullRequestLinter { private async communicateResult(result: ValidationCollector): Promise { const existingReview = await this.findExistingReview(); if (result.isValid()) { - console.log("✅ Success"); + console.log('✅ Success'); await this.dismissPRLinterReview(existingReview); } else { await this.createOrUpdatePRLinterReview(result.errors, existingReview); @@ -342,7 +342,7 @@ export class PullRequestLinter { * 7. It links to a p2 issue and has an approved community review */ private async assessNeedsReview( - pr: Pick, + pr: Pick, ): Promise { const reviews = await this.client.pulls.listReviews(this.prParams); // NOTE: MEMBER = a member of the organization that owns the repository @@ -350,19 +350,19 @@ export class PullRequestLinter { const maintainerRequestedChanges = reviews.data.some( review => review.author_association === 'MEMBER' && review.user?.login !== 'aws-cdk-automation' - && review.state === 'CHANGES_REQUESTED' + && review.state === 'CHANGES_REQUESTED', ); const maintainerApproved = reviews.data.some( review => review.author_association === 'MEMBER' - && review.state === 'APPROVED' + && review.state === 'APPROVED', ); const communityRequestedChanges = reviews.data.some( review => this.getTrustedCommunityMembers().includes(review.user?.login ?? '') - && review.state !== 'APPROVED' // community members cannot request changes - ) + && review.state !== 'APPROVED', // community members cannot request changes + ); const communityApproved = reviews.data.some( review => this.getTrustedCommunityMembers().includes(review.user?.login ?? '') - && review.state === 'APPROVED' + && review.state === 'APPROVED', ); const prLinterFailed = reviews.data.find((review) => review.user?.login === 'aws-cdk-automation' && review.state !== 'DISMISSED') as Review; @@ -394,7 +394,11 @@ export class PullRequestLinter { readyForReview = false; } - if (readyForReview && (fixesP1 || communityApproved)) { + // needs-maintainer-review means one of the following + // 1) fixes a p1 bug + // 2) is already community approved + // 3) is authored by a core team member + if (readyForReview && (fixesP1 || communityApproved || pr.labels.some(label => label.name === 'contribution/core'))) { this.addLabel('pr/needs-maintainer-review', pr); this.removeLabel('pr/needs-community-review', pr); } else if (readyForReview && !fixesP1) { @@ -406,7 +410,7 @@ export class PullRequestLinter { } } - private addLabel(label: string, pr: Pick) { + private addLabel(label: string, pr: Pick) { // already has label, so no-op if (pr.labels.some(l => l.name === label)) { return; } console.log(`adding ${label} to pr ${pr.number}`); @@ -420,7 +424,7 @@ export class PullRequestLinter { }); } - private removeLabel(label: string, pr: Pick) { + private removeLabel(label: string, pr: Pick) { // does not have label, so no-op if (!pr.labels.some(l => l.name === label)) { return; } console.log(`removing ${label} to pr ${pr.number}`); @@ -439,7 +443,7 @@ export class PullRequestLinter { private getTrustedCommunityMembers(): string[] { if (this.trustedCommunity.length > 0) { return this.trustedCommunity; } - const wiki = execSync('curl https://raw.githubusercontent.com/wiki/aws/aws-cdk/Introducing-CDK-Community-PR-Reviews.md', { encoding: 'utf-8'}).toString(); + const wiki = execSync('curl https://raw.githubusercontent.com/wiki/aws/aws-cdk/Introducing-CDK-Community-PR-Reviews.md', { encoding: 'utf-8' }).toString(); const rawMdTable = wiki.split('')[1].split('\n').filter(l => l !== ''); for (let i = 2; i < rawMdTable.length; i++) { this.trustedCommunity.push(rawMdTable[i].split('|')[1].trim()); @@ -460,48 +464,48 @@ export class PullRequestLinter { console.log(`⌛ Fetching files for PR number ${number}`); const files = await this.client.paginate(this.client.pulls.listFiles, this.prParams); - console.log("⌛ Validating..."); + console.log('⌛ Validating...'); const validationCollector = new ValidationCollector(pr, files); validationCollector.validateRuleSet({ exemption: shouldExemptReadme, exemptionMessage: `Not validating README changes since the PR is labeled with '${Exemption.README}'`, - testRuleSet: [ { test: featureContainsReadme } ], + testRuleSet: [{ test: featureContainsReadme }], }); validationCollector.validateRuleSet({ exemption: shouldExemptTest, exemptionMessage: `Not validating test changes since the PR is labeled with '${Exemption.TEST}'`, - testRuleSet: [ { test: featureContainsTest }, { test: fixContainsTest } ], + testRuleSet: [{ test: featureContainsTest }, { test: fixContainsTest }], }); validationCollector.validateRuleSet({ exemption: shouldExemptIntegTest, exemptionMessage: `Not validating integration test changes since the PR is labeled with '${Exemption.INTEG_TEST}'`, - testRuleSet: [ { test: featureContainsIntegTest}, { test: fixContainsIntegTest } ] + testRuleSet: [{ test: featureContainsIntegTest }, { test: fixContainsIntegTest }], }); validationCollector.validateRuleSet({ - testRuleSet: [ { test: validateBreakingChangeFormat } ] + testRuleSet: [{ test: validateBreakingChangeFormat }], }); validationCollector.validateRuleSet({ - testRuleSet: [ { test: validateTitlePrefix } ] + testRuleSet: [{ test: validateTitlePrefix }], }); validationCollector.validateRuleSet({ - testRuleSet: [ { test: validateTitleScope } ] - }) + testRuleSet: [{ test: validateTitleScope }], + }); validationCollector.validateRuleSet({ exemption: shouldExemptBreakingChange, exemptionMessage: `Not validating breaking changes since the PR is labeled with '${Exemption.BREAKING_CHANGE}'`, - testRuleSet: [ { test: assertStability } ] + testRuleSet: [{ test: assertStability }], }); validationCollector.validateRuleSet({ exemption: shouldExemptCliIntegTested, - testRuleSet: [ { test: noCliChanges } ], + testRuleSet: [{ test: noCliChanges }], }); await this.deletePRLinterComment(); @@ -527,19 +531,19 @@ export class PullRequestLinter { } function isPkgCfnspec(pr: GitHubPr): boolean { - return pr.title.indexOf("(cfnspec)") > -1; + return pr.title.indexOf('(cfnspec)') > -1; } function isFeature(pr: GitHubPr): boolean { - return pr.title.startsWith("feat") + return pr.title.startsWith('feat'); } function isFix(pr: GitHubPr): boolean { - return pr.title.startsWith("fix") + return pr.title.startsWith('fix'); } function testChanged(files: GitHubFile[]): boolean { - return files.filter(f => f.filename.toLowerCase().includes("test")).length != 0; + return files.filter(f => f.filename.toLowerCase().includes('test')).length != 0; } function integTestChanged(files: GitHubFile[]): boolean { @@ -547,11 +551,11 @@ function integTestChanged(files: GitHubFile[]): boolean { } function integTestSnapshotChanged(files: GitHubFile[]): boolean { - return files.filter(f => f.filename.toLowerCase().includes(".snapshot")).length != 0; + return files.filter(f => f.filename.toLowerCase().includes('.snapshot')).length != 0; } function readmeChanged(files: GitHubFile[]): boolean { - return files.filter(f => path.basename(f.filename) == "README.md").length != 0; + return files.filter(f => path.basename(f.filename) == 'README.md').length != 0; } function featureContainsReadme(pr: GitHubPr, files: GitHubFile[]): TestResult { @@ -627,7 +631,7 @@ function validateBreakingChangeFormat(pr: GitHubPr, _files: GitHubFile[]): TestR const m = re.exec(body ?? ''); if (m) { result.assessFailure(!m[0].startsWith('BREAKING CHANGE: '), `Breaking changes should be indicated by starting a line with 'BREAKING CHANGE: ', variations are not allowed. (found: '${m[0]}').`); - result.assessFailure(m[0].slice('BREAKING CHANGE:'.length).trim().length === 0, `The description of the first breaking change should immediately follow the 'BREAKING CHANGE: ' clause.`); + result.assessFailure(m[0].slice('BREAKING CHANGE:'.length).trim().length === 0, 'The description of the first breaking change should immediately follow the \'BREAKING CHANGE: \' clause.'); const titleRe = /^[a-z]+\([0-9a-z-_]+\)/; result.assessFailure(!titleRe.exec(title), 'The title of this pull request must specify the module name that the first breaking change should be associated to.'); } @@ -643,7 +647,7 @@ function validateTitlePrefix(pr: GitHubPr): TestResult { const m = titleRe.exec(pr.title); result.assessFailure( !m, - "The title of this pull request does not follow the Conventional Commits format, see https://www.conventionalcommits.org/."); + 'The title of this pull request does not follow the Conventional Commits format, see https://www.conventionalcommits.org/.'); return result; } @@ -654,7 +658,7 @@ function validateTitlePrefix(pr: GitHubPr): TestResult { */ function validateTitleScope(pr: GitHubPr): TestResult { const result = new TestResult(); - const scopesExemptFromThisRule = [ 'aws-cdk-lib' ]; + const scopesExemptFromThisRule = ['aws-cdk-lib']; // Specific commit types are handled by `validateTitlePrefix`. This just checks whether // the scope includes an `aws-` prefix or not. // Group 1: Scope with parens - "(aws-)" diff --git a/tools/@aws-cdk/prlint/module.ts b/tools/@aws-cdk/prlint/module.ts index 7aec7d042ba3d..3ee648e99047e 100644 --- a/tools/@aws-cdk/prlint/module.ts +++ b/tools/@aws-cdk/prlint/module.ts @@ -1,6 +1,6 @@ +import * as path from 'path'; import * as fs from 'fs-extra'; import * as glob from 'glob'; -import * as path from 'path'; let awsCdkLibPath: string; const modules: string[] = []; @@ -9,7 +9,7 @@ const awsCdkLibModules: string[] = []; export function findModulePath(fuzz: string): string { discoverModules(); - const regex = new RegExp(`[-_/]${fuzz}($|-alpha)`) + const regex = new RegExp(`[-_/]${fuzz}($|-alpha)`); const matched = [ ...modules.filter(m => regex.test(m)), ...(awsCdkLibModules.some(m => regex.test(m)) ? [awsCdkLibPath] : []), @@ -32,7 +32,7 @@ function discoverModules() { throw new Error('env REPO_ROOT must be set'); } const repoRoot = process.env.REPO_ROOT; - const lernaConfig = require(path.join(repoRoot, 'lerna.json')); + const lernaConfig = require(path.join(repoRoot, 'lerna.json')); // eslint-disable-line @typescript-eslint/no-require-imports const searchPaths: string[] = lernaConfig.packages; awsCdkLibPath = path.join(repoRoot, 'packages', 'aws-cdk-lib'); searchPaths.forEach(p => { @@ -67,6 +67,6 @@ export function moduleStability(loc: string): 'stable' | 'experimental' | undefi if (!fs.existsSync(path.join(loc, 'package.json'))) { throw new Error(`unexpected: no package.json found at location "${loc}"`); } - const pkgjson = require(path.join(loc, 'package.json')); + const pkgjson = require(path.join(loc, 'package.json')); // eslint-disable-line @typescript-eslint/no-require-imports return pkgjson.stability; } diff --git a/tools/@aws-cdk/prlint/package.json b/tools/@aws-cdk/prlint/package.json index 2056865f005da..46516673787c9 100644 --- a/tools/@aws-cdk/prlint/package.json +++ b/tools/@aws-cdk/prlint/package.json @@ -25,7 +25,12 @@ "@types/jest": "^29.5.3", "jest": "^29.6.1", "make-runnable": "^1.4.1", - "typescript": "~5.1.6" + "typescript": "~5.1.6", + "eslint": "^7.32.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-import-resolver-typescript": "^2.7.1", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^24.7.0" }, "jest": { "testMatch": [ @@ -37,6 +42,7 @@ "test": "jest", "build+test": "npm run build && npm run test", "build+test+extract": "npm run build+test", - "build+extract": "npm run build" + "build+extract": "npm run build", + "lint": "tsc -b && eslint . --ext=.ts" } } diff --git a/tools/@aws-cdk/prlint/test/lint.test.ts b/tools/@aws-cdk/prlint/test/lint.test.ts index efd09ad6ccd31..3fb5a595a1b6b 100644 --- a/tools/@aws-cdk/prlint/test/lint.test.ts +++ b/tools/@aws-cdk/prlint/test/lint.test.ts @@ -1,5 +1,5 @@ -import * as linter from '../lint'; import * as path from 'path'; +import * as linter from '../lint'; let mockRemoveLabel = jest.fn(); let mockAddLabel = jest.fn(); @@ -12,9 +12,9 @@ beforeAll(() => { process.env.REPO_ROOT = path.join(__dirname, '..', '..', '..', '..'); }); -afterEach(() => { +afterEach(() => { jest.clearAllMocks(); -}) +}); afterAll(() => { process.env.REPO_ROOT = undefined; @@ -25,11 +25,11 @@ let mockCreateReview: (errorMessage: string) => Promise; const SHA = 'ABC'; type Subset = { - [attr in keyof K]?: K[attr] extends object - ? Subset - : K[attr] extends object | null - ? Subset | null - : K[attr] extends object | null | undefined + [attr in keyof K]?: K[attr] extends object + ? Subset + : K[attr] extends object | null + ? Subset | null + : K[attr] extends object | null | undefined ? Subset | null | undefined : K[attr]; }; @@ -176,7 +176,7 @@ describe('commit message format', () => { }; const prLinter = configureMock(issue, undefined); expect(await prLinter.validatePullRequestTarget(SHA)).resolves; - }) + }); }); describe('ban breaking changes in stable modules', () => { @@ -267,14 +267,14 @@ describe('integration tests required on features', () => { }; const files = [ { - filename: 'integ.some-integ-test.ts' + filename: 'integ.some-integ-test.ts', }, { - filename: 'test/some-integ-test.integ.snapshot/integ.some-test.expected.json' + filename: 'test/some-integ-test.integ.snapshot/integ.some-test.expected.json', }, { - filename: 'README.md' - } + filename: 'README.md', + }, ]; const prLinter = configureMock(issue, files); expect(await prLinter.validatePullRequestTarget(SHA)).resolves; @@ -296,14 +296,14 @@ describe('integration tests required on features', () => { }; const files = [ { - filename: 'some-test.test.ts' + filename: 'some-test.test.ts', }, { - filename: 'test/some-integ-test.integ.snapshot/integ.some-test.expected.json' + filename: 'test/some-integ-test.integ.snapshot/integ.some-test.expected.json', }, { - filename: 'README.md' - } + filename: 'README.md', + }, ]; const prLinter = configureMock(issue, files); await expect(prLinter.validatePullRequestTarget(SHA)).rejects.toThrow( @@ -311,8 +311,8 @@ describe('integration tests required on features', () => { '\n\n\t❌ Features must contain a change to an integration test file and the resulting snapshot.' + '\n\nPRs must pass status checks before we can provide a meaningful review.\n\n' + 'If you would like to request an exemption from the status checks or clarification on feedback,' + - ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.' - ); + ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.', + ); }); test('integ snapshots not changed in feat', async () => { @@ -331,14 +331,14 @@ describe('integration tests required on features', () => { }; const files = [ { - filename: 'some-test.test.ts' + filename: 'some-test.test.ts', }, { - filename: 'integ.some-test.ts' + filename: 'integ.some-test.ts', }, { - filename: 'README.md' - } + filename: 'README.md', + }, ]; const prLinter = configureMock(issue, files); await expect(prLinter.validatePullRequestTarget(SHA)).rejects.toThrow( @@ -346,8 +346,8 @@ describe('integration tests required on features', () => { '\n\n\t❌ Features must contain a change to an integration test file and the resulting snapshot.' + '\n\nPRs must pass status checks before we can provide a meaningful review.\n\n' + 'If you would like to request an exemption from the status checks or clarification on feedback,' + - ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.' - ); + ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.', + ); }); test('integ files not changed in fix', async () => { @@ -366,14 +366,14 @@ describe('integration tests required on features', () => { }; const files = [ { - filename: 'some-test.test.ts' + filename: 'some-test.test.ts', }, { - filename: 'test/some-integ-test.integ.snapshot/integ.some-test.expected.json' + filename: 'test/some-integ-test.integ.snapshot/integ.some-test.expected.json', }, { - filename: 'README.md' - } + filename: 'README.md', + }, ]; const prLinter = configureMock(issue, files); await expect(prLinter.validatePullRequestTarget(SHA)).rejects.toThrow( @@ -381,8 +381,8 @@ describe('integration tests required on features', () => { '\n\n\t❌ Fixes must contain a change to an integration test file and the resulting snapshot.' + '\n\nPRs must pass status checks before we can provide a meaningful review.\n\n' + 'If you would like to request an exemption from the status checks or clarification on feedback,' + - ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.' - ); + ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.', + ); }); test('integ snapshots not changed in fix', async () => { @@ -401,14 +401,14 @@ describe('integration tests required on features', () => { }; const files = [ { - filename: 'some-test.test.ts' + filename: 'some-test.test.ts', }, { - filename: 'integ.some-test.ts' + filename: 'integ.some-test.ts', }, { - filename: 'README.md' - } + filename: 'README.md', + }, ]; const prLinter = configureMock(issue, files); await expect(prLinter.validatePullRequestTarget(SHA)).rejects.toThrow( @@ -416,8 +416,8 @@ describe('integration tests required on features', () => { '\n\n\t❌ Fixes must contain a change to an integration test file and the resulting snapshot.' + '\n\nPRs must pass status checks before we can provide a meaningful review.\n\n' + 'If you would like to request an exemption from the status checks or clarification on feedback,' + - ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.' - ); + ' please leave a comment on this PR containing `Exemption Request` and/or `Clarification Request`.', + ); }); test('integ files not changed, pr exempt', async () => { @@ -436,11 +436,11 @@ describe('integration tests required on features', () => { }; const files = [ { - filename: 'some-test.test.ts' + filename: 'some-test.test.ts', }, { - filename: 'README.md' - } + filename: 'README.md', + }, ]; const prLinter = configureMock(issue, files); expect(await prLinter.validatePullRequestTarget(SHA)).resolves; @@ -462,11 +462,11 @@ describe('integration tests required on features', () => { }; const files = [ { - filename: 'some-test.test.ts' + filename: 'some-test.test.ts', }, { - filename: 'readme.md' - } + filename: 'readme.md', + }, ]; const prlinter = configureMock(issue, files); expect(await prlinter.validatePullRequestTarget(SHA)).resolves; @@ -486,7 +486,7 @@ describe('integration tests required on features', () => { login: 'author', }, }; - const files = [ { filename: 'packages/aws-cdk/lib/cdk-toolkit.ts' } ]; + const files = [{ filename: 'packages/aws-cdk/lib/cdk-toolkit.ts' }]; test('no label throws error', async () => { const prLinter = configureMock(issue, files); @@ -511,23 +511,23 @@ describe('integration tests required on features', () => { const prLinter = configureMock(issue, files); await prLinter.validatePullRequestTarget(SHA); // THEN: no exception - }) + }); }); - describe('assess needs review from status event', () => { + describe('assess needs review from status event', () => { const pr = { draft: false, mergeable_state: 'behind', number: 1234, - labels: [{ name: 'p2'}], + labels: [{ name: 'p2' }], }; - beforeEach(() => { + beforeEach(() => { mockListReviews.mockImplementation(() => { return { data: [{ id: 1111122222, user: { login: 'aws-cdk-automation' }, state: 'DISMISSED' }], - } + }; }); - }) + }); test('needs a review', async () => { // WHEN @@ -540,10 +540,10 @@ describe('integration tests required on features', () => { // THEN expect(mockAddLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "labels": ["pr/needs-community-review"], - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + labels: ['pr/needs-community-review'], + owner: 'aws', + repo: 'aws-cdk', }); expect(mockRemoveLabel.mock.calls).toEqual([]); }); @@ -560,10 +560,10 @@ describe('integration tests required on features', () => { // THEN expect(mockAddLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "labels": ["pr/needs-maintainer-review"], - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + labels: ['pr/needs-maintainer-review'], + owner: 'aws', + repo: 'aws-cdk', }); expect(mockRemoveLabel.mock.calls).toEqual([]); }); @@ -573,12 +573,12 @@ describe('integration tests required on features', () => { mockListReviews.mockImplementation(() => { return { data: [{ id: 1111122222, user: { login: 'aws-cdk-automation' }, state: 'CHANGES_REQUESTED' }], - } + }; }); (pr as any).labels = [ { name: 'pr/needs-community-review', - } + }, ]; // WHEN @@ -591,10 +591,10 @@ describe('integration tests required on features', () => { // THEN expect(mockRemoveLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "name": "pr/needs-community-review", - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + name: 'pr/needs-community-review', + owner: 'aws', + repo: 'aws-cdk', }); expect(mockAddLabel.mock.calls).toEqual([]); }); @@ -604,12 +604,12 @@ describe('integration tests required on features', () => { mockListReviews.mockImplementation(() => { return { data: [{ id: 1111122222, user: { login: 'aws-cdk-automation' }, state: 'CHANGES_REQUESTED' }], - } + }; }); (pr as any).labels = [ { name: 'pr-linter/exemption-requested', - } + }, ]; // WHEN @@ -622,10 +622,10 @@ describe('integration tests required on features', () => { // THEN expect(mockAddLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "labels": ["pr/needs-community-review"], - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + labels: ['pr/needs-community-review'], + owner: 'aws', + repo: 'aws-cdk', }); expect(mockRemoveLabel.mock.calls).toEqual([]); }); @@ -638,7 +638,7 @@ describe('integration tests required on features', () => { { id: 1111122222, user: { login: 'aws-cdk-automation' }, state: 'CHANGES_REQUESTED' }, { id: 1111122223, user: { login: 'someuser' }, author_association: 'MEMBER', state: 'CHANGES_REQUESTED' }, ], - } + }; }); (pr as any).labels = [ { @@ -659,10 +659,10 @@ describe('integration tests required on features', () => { // THEN expect(mockRemoveLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "name": "pr/needs-community-review", - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + name: 'pr/needs-community-review', + owner: 'aws', + repo: 'aws-cdk', }); expect(mockAddLabel.mock.calls).toEqual([]); }); @@ -674,12 +674,12 @@ describe('integration tests required on features', () => { data: [ { id: 1111122223, user: { login: 'someuser' }, author_association: 'MEMBER', state: 'APPROVED' }, ], - } + }; }); (pr as any).labels = [ { name: 'pr/needs-community-review', - } + }, ]; // WHEN @@ -692,10 +692,10 @@ describe('integration tests required on features', () => { // THEN expect(mockRemoveLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "name": "pr/needs-community-review", - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + name: 'pr/needs-community-review', + owner: 'aws', + repo: 'aws-cdk', }); expect(mockAddLabel.mock.calls).toEqual([]); }); @@ -707,12 +707,12 @@ describe('integration tests required on features', () => { data: [ { id: 1111122223, user: { login: 'pahud' }, state: 'APPROVED' }, ], - } + }; }); (pr as any).labels = [ { name: 'pr/needs-community-review', - } + }, ]; // WHEN @@ -725,16 +725,16 @@ describe('integration tests required on features', () => { // THEN expect(mockRemoveLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "name": "pr/needs-community-review", - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + name: 'pr/needs-community-review', + owner: 'aws', + repo: 'aws-cdk', }); expect(mockAddLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "labels": ["pr/needs-maintainer-review"], - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + labels: ['pr/needs-maintainer-review'], + owner: 'aws', + repo: 'aws-cdk', }); }); @@ -745,12 +745,12 @@ describe('integration tests required on features', () => { data: [ { id: 1111122223, user: { login: 'pahud' }, state: 'COMMENT' }, ], - } + }; }); (pr as any).labels = [ { name: 'pr/needs-community-review', - } + }, ]; // WHEN @@ -763,10 +763,10 @@ describe('integration tests required on features', () => { // THEN expect(mockRemoveLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "name": "pr/needs-community-review", - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + name: 'pr/needs-community-review', + owner: 'aws', + repo: 'aws-cdk', }); expect(mockAddLabel.mock.calls).toEqual([]); }); @@ -778,12 +778,12 @@ describe('integration tests required on features', () => { data: [ { id: 1111122223, user: { login: 'untrusted' }, state: 'APPROVED' }, ], - } + }; }); (pr as any).labels = [ { name: 'pr/needs-community-review', - } + }, ]; // WHEN @@ -806,8 +806,8 @@ describe('integration tests required on features', () => { data: [ { id: 1111122222, user: { login: 'aws-cdk-automation' }, state: 'CHANGES_REQUESTED' }, { id: 1111122223, user: { login: 'someuser' }, author_association: 'MEMBER', state: 'CHANGES_REQUESTED' }, - ] - } + ], + }; }); (pr as any).title = 'blah'; (pr as any).labels = [ @@ -816,7 +816,7 @@ describe('integration tests required on features', () => { }, { name: 'pr/needs-community-review', - } + }, ]; // WHEN @@ -825,10 +825,10 @@ describe('integration tests required on features', () => { // THEN expect(mockRemoveLabel.mock.calls[0][0]).toEqual({ - "issue_number": 1234, - "name": "pr/needs-community-review", - "owner": "aws", - "repo": "aws-cdk", + issue_number: 1234, + name: 'pr/needs-community-review', + owner: 'aws', + repo: 'aws-cdk', }); expect(mockAddLabel.mock.calls).toEqual([]); }); @@ -848,7 +848,7 @@ function configureMock(pr: Subset, prFiles?: linter.GitHubFile[ createReview(errorMessage: string) { return { promise: () => mockCreateReview(errorMessage), - } + }; }, listReviews: mockListReviews, @@ -862,7 +862,7 @@ function configureMock(pr: Subset, prFiles?: linter.GitHubFile[ deleteComment() {}, listComments() { - return { data: [{ id: 1212121212, user: { login: 'aws-cdk-automation' }, body: 'The pull request linter fails with the following errors:' }] } + return { data: [{ id: 1212121212, user: { login: 'aws-cdk-automation' }, body: 'The pull request linter fails with the following errors:' }] }; }, removeLabel: mockRemoveLabel, @@ -876,7 +876,7 @@ function configureMock(pr: Subset, prFiles?: linter.GitHubFile[ context: linter.CODE_BUILD_CONTEXT, state: 'success', }], - } + }; }, }; @@ -894,7 +894,7 @@ function configureMock(pr: Subset, prFiles?: linter.GitHubFile[ issues: issuesClient as any, search: searchClient as any, repos: reposClient as any, - paginate: (method: any, args: any) => { return method(args).data }, + paginate: (method: any, args: any) => { return method(args).data; }, } as any, - }) + }); } diff --git a/tools/@aws-cdk/prlint/test/module.test.ts b/tools/@aws-cdk/prlint/test/module.test.ts index 47947b9fd539b..933dd3ea9407b 100644 --- a/tools/@aws-cdk/prlint/test/module.test.ts +++ b/tools/@aws-cdk/prlint/test/module.test.ts @@ -1,5 +1,5 @@ -import { findModulePath, moduleStability } from '../module'; import * as path from 'path'; +import { findModulePath, moduleStability } from '../module'; const repoRoot = path.join(__dirname, '..', '..', '..', '..'); @@ -52,4 +52,4 @@ describe('moduleStability', () => { function absolute(loc: string) { return path.join(repoRoot, loc); } -}) +});