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
1588: Bridge messages should not be sent for PRs in draft state #1469
Conversation
👋 Welcome back gli! A progress list of the required criteria for merging this PR into |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this patch could successfully help us postpone the sending of emails when the pr is in draft mode and some users will be happy to see this update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure whether this is sufficient. See my question below.
@@ -203,6 +203,7 @@ public List<WorkItem> getPeriodicItems() { | |||
|
|||
List<PullRequest> prs = poller.updatedPullRequests(); | |||
prs.stream() | |||
.filter(pr -> !pr.isDraft()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure this is the right place to do this? The intention of this fix is to pause notifications for Draft PRs until it becomes "rfr" again, just like it currently does for PRs initially in Draft that become "rfr" for the first time. Will it do this or will it just lose the notifications permanently?
// Make it as draft again. | ||
pr.makeDraft(); | ||
|
||
// Add a new comment. | ||
pr.addComment("This is a new comment"); | ||
|
||
// Run another archive pass. | ||
TestBotRunner.runPeriodicItems(mlBot); | ||
|
||
// The archive should not now contain the new comment. | ||
Repository.materialize(archiveFolder.path(), archive.url(), "master"); | ||
assertEquals(2, archiveContainsCount(archiveFolder.path(), "RFR: 1234: This is a pull request")); | ||
assertEquals(1, archiveContainsCount(archiveFolder.path(), "This is a comment")); | ||
assertFalse(archiveContains(archiveFolder.path(), "This is a new comment")); | ||
|
||
// Make it as not draft again. | ||
pr.makeNotDraft(); | ||
|
||
// Run another archive pass. | ||
TestBotRunner.runPeriodicItems(mlBot); | ||
|
||
// The archive should now contain the new comment. | ||
Repository.materialize(archiveFolder.path(), archive.url(), "master"); | ||
assertEquals(3, archiveContainsCount(archiveFolder.path(), "RFR: 1234: This is a pull request")); | ||
assertEquals(1, archiveContainsCount(archiveFolder.path(), "This is a comment")); | ||
assertEquals(1, archiveContainsCount(archiveFolder.path(), "This is a new comment")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kevinrushforth Hi Kevin, see Li's test case here. This pr was 'rfr' and he converted it to draft. When the pr was in draft mode, he added a comment 'This is a new comment' and run the bot. As expected, there is no email sent. After that, he converted the pr to 'rfr' again and run the bot. This time, he got the notification about the comment 'This is a new comment'. So we won't lose the notification permanently. It's just delayed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will indeed pause emails while a PR is in draft state. When it gets back from draft, I believe everything that happened while in draft will be sent. That is certainly the easiest way to handle this and I'm good with this change. We will just have to see how it plays out in practice.
Thinking about this some more, this simple solution has a pretty big drawback. There is no actual synchronization between events. All bot actions are asynchronous. Imagine the following scenario.
For this to work correctly, draft PRs still need to be processed by mlbridge, and any events up until the draft state change need to be processed as usual. This is still possibly better than what we have, but I'm not sure. Opinions? |
I'm not sure I understand it correctly. Is the problem that the notification 'I'm putting this PR in draft to work on the feedback' won't be sent until the user makes the PR out of draft mode? Maybe it's not a big problem, the window is not very big, just few minutes. |
Yes, the problem is that the last comments or events before changing a PR to draft could be delayed until the PR is taken out of draft. The size of the window for this to happen is usually just a few minutes, but depending on the state of the bots, it could be much longer. My example scenario seems like a very plausible series of events however, a user comments about making it draft and then puts it in draft, more or less at the same time. In that case it's very likely that the last comment hits the window. Also delaying that particular message would be very confusing to users, and I can guarantee that if it happened, we would get a lot of complaints. A PR could be moved to draft for weeks, and suddenly receiving week old comments from before it was put in draft is pretty bad. |
Ok, I think the solution is that we don't filter in |
There should be events that we can query for with timestamps for when the state change happened. The check would be something like this: If pr.isDraft(), find last event that put it in draft and use the timestamp of that as filter for any email generation. |
Good Caught. This is a case we need to solve. I updated the code just now, which ignores the comments in method In order to get the time when the PR was last marked as draft, I add a new API |
Now, I could remember that my implementation of SKARA-1683 shares the same issue with Li's first version. I had previously mentioned in that pr "My current implementation has a bug. If a user force-pushes or rebases when the pr is in ready state, and then he converts the pr to draft state very quickly, in such a case, our pullRequestBot won't have enough time to send warning, and then user will never get the notification of this force-push or rebase.". I will fix this issue later this week . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good, but see comments. Were you able to run the manual tests to verify the new methods on PullRequest?
// If the pull request was converted to draft, the comments | ||
// after the last converted time should be ignored. | ||
if (pr.isDraft()) { | ||
var lastDraftTime = pr.lastMarkedAsDraftTime(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method gets called for every comment on the PR, every time ArchiveWorkItem
is run for a PR. The result of pr.lastMarkedAsDraftTime()
needs to be retrieved once and reused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I move pr.lastMarkedAsDraftTime()
to the method ArchiveWorkItem#run
to avoid the duplicated invocation.
.map(JSONValue::asObject) | ||
.filter(obj -> obj.contains("event")) | ||
.filter(obj -> obj.get("event").asString().equals("convert_to_draft")) | ||
.reduce((a, b) -> b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure of the order events are returned in? I couldn't find a definition of the order. Maybe safer to map to date and reduce to the highest one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find the related document too. I tried the rest api to get the related data and found the order personally. Now I adjust the code to find the highest one to avoid the API result changes in the future.
.map(JSONValue::asObject) | ||
.filter(obj -> obj.get("system").asBoolean()) | ||
.filter(obj -> draftMessage.equals(obj.get("body").asString())) | ||
.reduce((a, b) -> a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here as for GitHub, maybe reduce to highest date just to be safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above and also adjust it.
…ust the API implementation.
I had run the manual tests locally. Everything looks fine. |
.filter(obj -> obj.contains("event")) | ||
.filter(obj -> obj.get("event").asString().equals("convert_to_draft")) | ||
.map(obj -> ZonedDateTime.parse(obj.get("created_at").asString())) | ||
.reduce((a, b) -> a.isBefore(b) ? b : a); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be expressed as max()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@lgxbslgx This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. 🔍 One or more changes in this pull request modifies files in areas of the source code that often require two reviewers. Please consider if this is the case for this pull request, and if so, await a second reviewer to approve this pull request before you integrate it. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been no new commits pushed to the ➡️ To integrate this PR with the above commit message to the |
It seems a new bug: When a PR has become ready and then another PR, of which code conflicts with the former one, was integrated, the former PR remains ready. But actually, it should have a This PR-1469 (SKARA-1588) has became ready and then PR-1472 (SKARA-1817) was integrated. This PR is still ready now. But actually, this PR should have a I suspect it is because PR bot have not been triggered in this PR (since this PR has not been updated). This comment can update this PR and can verify my idea. |
# Conflicts: # forge/src/test/java/org/openjdk/skara/forge/gitlab/GitLabRestApiTest.java
This suspicion looks wrong now. |
Filed https://bugs.openjdk.org/browse/SKARA-1820 to record it. |
/integrate |
Going to push as commit baa4fae. |
Hi all,
This patch prevents the
mailling bridge bot
from sending emails when a PR is draft.And the related test case is added.
Thanks for taking the time to review.
Best Regards,
-- Guoxiong
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/skara pull/1469/head:pull/1469
$ git checkout pull/1469
Update a local copy of the PR:
$ git checkout pull/1469
$ git pull https://git.openjdk.org/skara pull/1469/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1469
View PR using the GUI difftool:
$ git pr show -t 1469
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/skara/pull/1469.diff