Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update workflow to not close unreviewed stale PRs #3

Closed
wants to merge 2 commits into from

Conversation

paulhcsun
Copy link

Problem:
Currently this github workflow is closing stale PRs even if they have not yet been reviewed by a core member.

Ideally a PR should never sit long enough to go stale without being reviewed but update will ensure that even in that scenario the PR will not be automatically closed.

Solution:
Check for at least 1 core member comment or review on the PR, it there are none then trigger the warn action instead of the close action when the PR becomes stale.

Copy link

@scanlonp scanlonp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments on the function implementation.

src/stale-prs.ts Outdated
Comment on lines 350 to 355
const reviews = (await this.client.paginate(this.client.rest.pulls.listReviews, { ...this.repo, pull_number }));

const comments = await this.client.paginate(this.client.rest.issues.listComments, {
...this.repo,
issue_number: pull_number,
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will all reviews leave comments? If so do we need to look through the reviews?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: these lines are formatted differently.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya I wasn't 100% sure if issues.listComments would also include reviews hence the separate check, though I don't think it'd hurt to keep the check for reviews.

src/stale-prs.ts Outdated
Comment on lines 350 to 365
const reviews = (await this.client.paginate(this.client.rest.pulls.listReviews, { ...this.repo, pull_number }));

const comments = await this.client.paginate(this.client.rest.issues.listComments, {
...this.repo,
issue_number: pull_number,
});

// Reviews by team members
// Filtering out instances where submitted_at is empty
const memberReviews = reviews.filter(r => r.author_association === 'MEMBER').filter(r => r.submitted_at);

// Comments by team members
// Filtering out instances where submitted_at is empty
const memberComments = comments.filter(r => r.author_association === 'MEMBER').filter(r => r.submitted_at);

return memberComments.length > 0 || memberReviews.length > 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are looking for either reviews or comments, can we do them one at a time. Why do we need to request all of the reviews and all of the comments all at once? Say we find a comment from a core team member, then we do not need to make a request for the reviews.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll change this to only check reviews if after confirming there are no core member comments.

*/
private async memberReviewed(pull_number: number): Promise<Boolean> {

const comments = (await this.client.paginate(this.client.rest.issues.listComments, { ...this.repo, issue_number: pull_number, }));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are looking for reviews, why do we check for comments?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also check for comments in case a core member only decides to just leave a comment on the PR (maybe to answer a question or point the contributor in the right direction) without actually submitting a review. In this case we've still responded to the PR and now it's up to the contributor to continue. I'm not sure how often this would occur though, perhaps just looking at reviews is sufficient?

// Filtering out instances where submitted_at is empty
const memberComments = comments.filter(r => r.author_association === 'MEMBER').filter(r => r.submitted_at);

if (!(memberComments.length > 0)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turn this into an early return, instead of a large nested if:

if (memberComments.length > 0) {
  return true;
}

// Else check for another source of truth

In general, try to avoid long if blocks if you can; the code will be easier to follow that way.


// Reviews by team members
// Filtering out instances where submitted_at is empty
const memberReviews = reviews.filter(r => r.author_association === 'MEMBER').filter(r => r.submitted_at);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can remember that author_association is not visible if the calling account is not part of the target organization; and our bots are not members of the target organization (mandated by our security department).

Are we using this condition elsewhere already?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's being used in the reviewState() method which is where I copied this line from.

Comment on lines +157 to +160
const memberReviewed = await this.memberReviewed(pull.number);

const warning = warnings.get('STALE PR');
if (!warning || warning < stale.since) {
if (!warning || warning < stale.since || !memberReviewed) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct?

This is saying:

  1. If we don't have a warning yet
  2. OR the last warning we gave is from before the start of the current staleness period
  3. OR the PR hasn't been reviewed yet

THEN we should add a warning and start the timer for closing.

For fresh PRs, the 3rd condition will be automatically true, because at the start nobody will have looked at it yet.

So this would add a staleness warning immediately on every new PR!


I think what you probably want is to have memberReviewed factor into the value of stale: a PR should not be considered stale if it hasn't been reviewed yet.

Have a look at line 115, and think about how your change would interact with the conditions that are laid out there -- then make the changes over there.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good catch, I was thinking this would only be run if the PR is already stale but the stale variable includes any build failures and merge conflicts as well. I'll update it with your suggestion.

@paulhcsun
Copy link
Author

After getting some more context on why this workflow was built and reviewing the stale closed PRs that prompted this change, I'm going to decide to close this as I believe the github action is working as intended. The PRs that were closed automatically closed that prompted this PR (aws/aws-cdk#27693, aws/aws-cdk#27756, aws/aws-cdk#27711) were unreviewed but also in a build failing state. A decision could be made in future construct squads to still try to review those PRs and not close them but for now we will keep this action as is.

A potential alternative is to instead add a help-requested tag along with the stale warning for build-failures/change-requested states that allow us or community reviewers to provide guidance on.

@paulhcsun paulhcsun closed this Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants