Skip to content

Commit

Permalink
Add ReviewDrafter handler (#156)
Browse files Browse the repository at this point in the history
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
  • Loading branch information
ludeeus and frenck authored Feb 8, 2023
1 parent 15bb1af commit b4d966c
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions services/bots/src/github-webhook/github-webhook.const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export enum EventType {
PULL_REQUEST_LABELED = 'pull_request.labeled',
PULL_REQUEST_OPENED = 'pull_request.opened',
PULL_REQUEST_REOPENED = 'pull_request.reopened',
PULL_REQUEST_READY_FOR_REVIEW = 'pull_request.ready_for_review',
PULL_REQUEST_REVIEW_SUBMITTED = 'pull_request_review.submitted',
PULL_REQUEST_SYNCHRONIZE = 'pull_request.synchronize',
PULL_REQUEST_UNLABELED = 'pull_request.unlabeled',
Expand Down
2 changes: 2 additions & 0 deletions services/bots/src/github-webhook/github-webhook.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { QualityScaleLabeler } from './handlers/quality_scale';
import { SetDocumentationSection } from './handlers/set_documentation_section';
import { SetIntegration } from './handlers/set_integration';
import { ValidateCla } from './handlers/validate-cla';
import { ReviewDrafter } from './handlers/review_drafter';

@Module({
providers: [
Expand All @@ -41,6 +42,7 @@ import { ValidateCla } from './handlers/validate-cla';
MonthOfWTH,
PlatinumReview,
QualityScaleLabeler,
ReviewDrafter,
SetDocumentationSection,
SetIntegration,
SetIntentsLanguage,
Expand Down
82 changes: 82 additions & 0 deletions services/bots/src/github-webhook/handlers/review_drafter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
PullRequestReadyForReviewEvent,
PullRequestReviewSubmittedEvent,
} from '@octokit/webhooks-types';
import { EventType, HomeAssistantRepository } from '../github-webhook.const';
import { WebhookContext } from '../github-webhook.model';
import { BaseWebhookHandler } from './base';

const MESSAGE_ID = '<!-- ReviewDrafterComment -->';

const REVIEW_COMMENT = `${MESSAGE_ID}
Please take a look at the requested changes, and use the **Ready for review** button when you are done, thanks :+1:
[_Learn more about our pull request process._](https://developers.home-assistant.io/blog/2023/02/07/introducing-PR-drafting-in-reviews)
`;

export class ReviewDrafter extends BaseWebhookHandler {
public allowedEventTypes = [
EventType.PULL_REQUEST_REVIEW_SUBMITTED,
EventType.PULL_REQUEST_READY_FOR_REVIEW,
];
public allowedRepositories = [HomeAssistantRepository.CORE];

async handle(
context: WebhookContext<PullRequestReviewSubmittedEvent | PullRequestReadyForReviewEvent>,
) {
if (context.eventType === EventType.PULL_REQUEST_REVIEW_SUBMITTED) {
await this.handleReviewCommentSubmitted(
context as WebhookContext<PullRequestReviewSubmittedEvent>,
);
} else if (context.eventType === EventType.PULL_REQUEST_READY_FOR_REVIEW) {
await this.handleReadyForReview(context as WebhookContext<PullRequestReadyForReviewEvent>);
}
}

async handleReviewCommentSubmitted(context: WebhookContext<PullRequestReviewSubmittedEvent>) {
if (
context.payload.pull_request.draft ||
context.payload.review.state !== 'changes_requested'
) {
// We only care about changes_requested on non-draft PRs
return;
}
const currentComments = await context.github.issues.listComments(
context.issue({ per_page: 100 }),
);
if (!currentComments.data.find((comment) => comment.body.startsWith(MESSAGE_ID))) {
// No comment found, add one
await context.github.issues.createComment(
context.issue({
body: REVIEW_COMMENT,
}),
);
}

// Mark PR as draft, this is not available in the REST API, so we need to use GraphQL
await context.github.graphql({
query: `mutation { convertPullRequestToDraft(input: {pullRequestId: "${context.payload.pull_request.node_id}"}) {}}`,
});
}

async handleReadyForReview(context: WebhookContext<PullRequestReadyForReviewEvent>) {
const currentComments = await context.github.issues.listComments(
context.issue({ per_page: 100 }),
);
if (!currentComments.data.find((comment) => comment.body.startsWith(MESSAGE_ID))) {
// We did not add the comment, so we should not request a review
return;
}

const { data: currentRewiewers } = await context.github.pulls.listRequestedReviewers(
context.pullRequest(),
);
// Request review from all users and teams that are currently requested
await context.github.pulls.requestReviewers(
context.pullRequest({
reviewers: currentRewiewers.users.map((user) => user.login),
team_reviewers: currentRewiewers.teams.map((team) => team.slug),
}),
);
}
}

0 comments on commit b4d966c

Please sign in to comment.