@@ -1152,79 +1152,116 @@ proceedUntilFixedPoint state = do
11521152 then return state
11531153 else proceedUntilFixedPoint newState
11541154
1155- -- Describe the status of the pull request.
1156- describeStatus :: BaseBranch -> PullRequestId -> PullRequest -> ProjectState -> Text
1157- describeStatus (BaseBranch projectBaseBranchName) prId pr state = case Pr. classifyPullRequest pr of
1158- PrStatusAwaitingApproval -> " Pull request awaiting approval."
1155+ -- | Feedback on a successfully parsed command.
1156+ data Feedback
1157+ = -- | Leave a comment.
1158+ CommentFeedback Text
1159+ | -- | Leave only a reaction.
1160+ ReactionFeedback ReactableId GithubApi. ReactionContent
1161+
1162+ -- | Determine what kind of feedback to leave based on the status of a PR.
1163+ feedbackOnStatus :: BaseBranch -> PullRequestId -> PullRequest -> ProjectState -> Feedback
1164+ feedbackOnStatus (BaseBranch projectBaseBranchName) prId pr state = case Pr. classifyPullRequest pr of
1165+ PrStatusAwaitingApproval -> CommentFeedback " Pull request awaiting approval."
11591166 PrStatusApproved ->
11601167 let
1161- Approval (Username approvedBy) _source approvalType _position retriedBy priority = fromJust $ Pr. approval pr
1168+ Approval (Username approvedBy) source approvalType _position retriedBy priority = fromJust $ Pr. approval pr
11621169
11631170 approvalCommand = Pr. displayMergeCommand (Approve approvalType)
11641171 retriedByMsg = case retriedBy of
11651172 Just user -> format " (retried by @{})" [user]
11661173 Nothing -> mempty
1167- queuePositionMsg = case Pr. getQueuePosition prId state of
1174+ queuePosition = Pr. getQueuePosition prId state
1175+ queuePositionMsg = case queuePosition of
11681176 0 -> " rebasing now"
11691177 1 -> " waiting for rebase behind one pull request"
11701178 n -> format " waiting for rebase behind {} pull requests" [n]
11711179 priorityMsg = case priority of
11721180 Normal -> mempty
11731181 High -> " with high priority"
1174- in format " Pull request approved for {}{} by @{}{}, {}." [approvalCommand, priorityMsg, approvedBy, retriedByMsg, queuePositionMsg]
1182+ in
1183+ case (queuePosition, source) of
1184+ (0 , Just reactable) -> ReactionFeedback reactable GithubApi. PlusOne
1185+ _ ->
1186+ CommentFeedback $
1187+ format
1188+ " Pull request approved for {}{} by @{}{}, {}."
1189+ [approvalCommand, priorityMsg, approvedBy, retriedByMsg, queuePositionMsg]
11751190 PrStatusOutdated ->
11761191 let BaseBranch baseBranchName = Pr. baseBranch pr
1177- in format " Push to {} detected, rebasing again." [baseBranchName]
1178- PrStatusBuildPending -> let Sha sha = fromJust $ Pr. integrationSha pr
1179- train = takeWhile (/= prId) $ Pr. unfailedIntegratedPullRequests state
1180- len = length train
1181- prs = if len == 1 then " PR" else " PRs"
1182- in case train of
1183- [] -> Text. concat [" Rebased as " , sha, " , waiting for CI …" ]
1184- (_: _) -> Text. concat [ " Speculatively rebased as " , sha
1185- , " behind " , Text. pack $ show len
1186- , " other " , prs
1187- , " , waiting for CI …"
1188- ]
1189- PrStatusBuildStarted url -> Text. concat [" [CI job :yellow_circle:](" , url, " ) started." ]
1190- PrStatusAwaitingPromotion -> " The PR is waiting to be pushed to the target branch"
1191- PrStatusIntegrated -> " The build succeeded."
1192+ in CommentFeedback $ format " Push to {} detected, rebasing again." [baseBranchName]
1193+ PrStatusBuildPending ->
1194+ let Sha sha = fromJust $ Pr. integrationSha pr
1195+ train = takeWhile (/= prId) $ Pr. unfailedIntegratedPullRequests state
1196+ len = length train
1197+ prs = if len == 1 then " PR" else " PRs"
1198+ in CommentFeedback $ case train of
1199+ [] -> Text. concat [" Rebased as " , sha, " , waiting for CI …" ]
1200+ (_ : _) ->
1201+ Text. concat
1202+ [ " Speculatively rebased as "
1203+ , sha
1204+ , " behind "
1205+ , Text. pack $ show len
1206+ , " other "
1207+ , prs
1208+ , " , waiting for CI …"
1209+ ]
1210+ PrStatusBuildStarted url -> CommentFeedback $ Text. concat [" [CI job :yellow_circle:](" , url, " ) started." ]
1211+ PrStatusAwaitingPromotion -> CommentFeedback $ " The PR is waiting to be pushed to the target branch"
1212+ PrStatusIntegrated -> CommentFeedback $ " The build succeeded."
11921213 PrStatusIncorrectBaseBranch ->
11931214 let BaseBranch baseBranchName = Pr. baseBranch pr
1194- in format " Merge rejected: the base branch of this pull request must be set to {}. It is currently set to {}."
1195- [projectBaseBranchName, baseBranchName]
1196- PrStatusWrongFixups -> " Pull request cannot be integrated as it contains fixup commits that do not belong to any other commits."
1197- PrStatusEmptyRebase -> " Empty rebase. \
1198- \ Have the changes already been merged into the target branch? \
1199- \ Aborting."
1215+ in CommentFeedback $
1216+ format
1217+ " Merge rejected: the base branch of this pull request must be set to {}. It is currently set to {}."
1218+ [projectBaseBranchName, baseBranchName]
1219+ PrStatusWrongFixups ->
1220+ CommentFeedback " Pull request cannot be integrated as it contains fixup commits that do not belong to any other commits."
1221+ PrStatusEmptyRebase ->
1222+ CommentFeedback
1223+ " Empty rebase. \
1224+ \ Have the changes already been merged into the target branch? \
1225+ \ Aborting."
12001226 PrStatusFailedConflict ->
12011227 let
12021228 BaseBranch targetBranchName = Pr. baseBranch pr
12031229 Branch prBranchName = Pr. branch pr
1204- in Text. concat
1205- [ " Failed to rebase, please rebase manually using\n\n "
1206- , " git fetch && git rebase --interactive --autosquash origin/"
1207- , targetBranchName
1208- , " "
1209- , prBranchName
1210- ]
1230+ in
1231+ CommentFeedback $
1232+ Text. concat
1233+ [ " Failed to rebase, please rebase manually using\n\n "
1234+ , " git fetch && git rebase --interactive --autosquash origin/"
1235+ , targetBranchName
1236+ , " "
1237+ , prBranchName
1238+ ]
12111239 -- The following is not actually shown to the user
12121240 -- as it is never set with needsFeedback=True,
12131241 -- but here in case we decide to show it.
1214- PrStatusSpeculativeConflict -> " Failed to speculatively rebase. \
1215- \ I will retry rebasing automatically when the queue clears."
1216- PrStatusFailedBuild url -> case Pr. unfailedIntegratedPullRequestsBefore pr state of
1217- -- On Fridays the retry command is also `retry on friday`. We currently
1218- -- don't have that information here. Is that worth including?
1219- [] -> format " The {}.\n\n \
1220- \If this is the result of a flaky test, \
1221- \then tag me again with the `retry` command. \
1222- \Otherwise, push a new commit and tag me again."
1223- [markdownLink " build failed :x:" url]
1224- trainBefore -> format " Speculative {}. \
1225- \ I will automatically retry after getting build results for {}."
1226- [ markdownLink " build failed :x:" url
1227- , prettyPullRequestIds trainBefore ]
1242+ PrStatusSpeculativeConflict ->
1243+ CommentFeedback
1244+ " Failed to speculatively rebase. \
1245+ \ I will retry rebasing automatically when the queue clears."
1246+ PrStatusFailedBuild url ->
1247+ CommentFeedback $
1248+ case Pr. unfailedIntegratedPullRequestsBefore pr state of
1249+ -- On Fridays the retry command is also `retry on friday`. We currently
1250+ -- don't have that information here. Is that worth including?
1251+ [] ->
1252+ format
1253+ " The {}.\n\n \
1254+ \If this is the result of a flaky test, \
1255+ \then tag me again with the `retry` command. \
1256+ \Otherwise, push a new commit and tag me again."
1257+ [markdownLink " build failed :x:" url]
1258+ trainBefore ->
1259+ format
1260+ " Speculative {}. \
1261+ \ I will automatically retry after getting build results for {}."
1262+ [ markdownLink " build failed :x:" url
1263+ , prettyPullRequestIds trainBefore
1264+ ]
12281265
12291266-- Leave a comment with the feedback from 'describeStatus' and set the
12301267-- 'needsFeedback' flag to 'False'.
@@ -1235,11 +1272,15 @@ leaveFeedback
12351272 -> Eff es ProjectState
12361273leaveFeedback (prId, pr) state = do
12371274 projectBaseBranch <- getBaseBranch
1238- let message = describeStatus projectBaseBranch prId pr state
1239- -- Hoff shouldn't reply to any of its own feedback messages. This can happen
1240- -- if external automation causes the bot to issue a merge command to itself.
1241- -- In that case the bot may tag itself when the merge gets approved.
1242- () <- leaveComment prId $ hoffIgnoreComment <> message
1275+ case feedbackOnStatus projectBaseBranch prId pr state of
1276+ CommentFeedback message ->
1277+ -- Hoff shouldn't reply to any of its own feedback messages. This can happen
1278+ -- if external automation causes the bot to issue a merge command to itself.
1279+ -- In that case the bot may tag itself when the merge gets approved.
1280+ leaveComment prId $ hoffIgnoreComment <> message
1281+ ReactionFeedback reactable reaction ->
1282+ addReaction reactable reaction
1283+
12431284 pure $ Pr. setNeedsFeedback prId False state
12441285
12451286-- Run 'leaveFeedback' on all pull requests that need feedback.
0 commit comments