Skip to content

Commit b83aae5

Browse files
Merge pull request #3111 from scala-steward-org/reload-pr-body
Ensure PR bodies and titles are recreated when updating PRs
2 parents 23ab129 + a340d37 commit b83aae5

File tree

12 files changed

+276
-28
lines changed

12 files changed

+276
-28
lines changed

modules/core/src/main/scala/org/scalasteward/core/forge/ForgeApiAlg.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ trait ForgeApiAlg[F[_]] {
2727

2828
def createPullRequest(repo: Repo, data: NewPullRequestData): F[PullRequestOut]
2929

30+
def updatePullRequest(number: PullRequestNumber, repo: Repo, data: NewPullRequestData): F[Unit]
31+
3032
def closePullRequest(repo: Repo, number: PullRequestNumber): F[PullRequestOut]
3133

3234
def getBranch(repo: Repo, branch: Branch): F[BranchOut]

modules/core/src/main/scala/org/scalasteward/core/forge/azurerepos/AzureReposApiAlg.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ final class AzureReposApiAlg[F[_]](
5454
} yield pullRequestOut
5555
}
5656

57+
override def updatePullRequest(
58+
number: PullRequestNumber,
59+
repo: Repo,
60+
data: NewPullRequestData
61+
): F[Unit] =
62+
logger.warn("Updating PRs is not yet supported for Azure Repos")
63+
5764
// https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull-requests/update?view=azure-devops-rest-7.1
5865
override def closePullRequest(repo: Repo, number: PullRequestNumber): F[PullRequestOut] =
5966
client.patchWithBody[PullRequestOut, ClosePullRequestPayload](

modules/core/src/main/scala/org/scalasteward/core/forge/bitbucket/BitbucketApiAlg.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ class BitbucketApiAlg[F[_]](
9797
} yield pullRequestOut
9898
}
9999

100+
override def updatePullRequest(
101+
number: PullRequestNumber,
102+
repo: Repo,
103+
data: NewPullRequestData
104+
): F[Unit] =
105+
logger.warn("Updating PRs is not yet supported for Bitbucket")
106+
100107
override def getBranch(repo: Repo, branch: Branch): F[BranchOut] =
101108
client.get(url.branch(repo, branch), modify(repo))
102109

modules/core/src/main/scala/org/scalasteward/core/forge/bitbucketserver/BitbucketServerApiAlg.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ final class BitbucketServerApiAlg[F[_]](
8686
} yield pr.toPullRequestOut
8787
}
8888

89+
override def updatePullRequest(
90+
number: PullRequestNumber,
91+
repo: Repo,
92+
data: NewPullRequestData
93+
): F[Unit] =
94+
logger.warn("Updating PRs is not yet supported for Bitbucket Server")
95+
8996
private def useDefaultReviewers(repo: Repo): F[List[Reviewer]] =
9097
if (config.useDefaultReviewers) getDefaultReviewers(repo) else F.pure(List.empty[Reviewer])
9198

modules/core/src/main/scala/org/scalasteward/core/forge/gitea/GiteaApiAlg.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,13 @@ final class GiteaApiAlg[F[_]: HttpJsonClient](
186186
)
187187
} yield pullRequestOut(resp)
188188

189+
override def updatePullRequest(
190+
number: PullRequestNumber,
191+
repo: Repo,
192+
data: NewPullRequestData
193+
): F[Unit] =
194+
logger.warn("Updating PRs is not yet supported for Gitea")
195+
189196
override def closePullRequest(repo: Repo, number: PullRequestNumber): F[PullRequestOut] = {
190197
val edit = EditPullRequestOption(state = "closed")
191198
client

modules/core/src/main/scala/org/scalasteward/core/forge/github/PullRequestPayload.scala renamed to modules/core/src/main/scala/org/scalasteward/core/forge/github/CreatePullRequestPayload.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@ import io.circe.generic.semiauto.deriveEncoder
2121
import org.scalasteward.core.forge.data.NewPullRequestData
2222
import org.scalasteward.core.git.Branch
2323

24-
final case class PullRequestPayload(
24+
final case class CreatePullRequestPayload(
2525
title: String,
2626
body: String,
2727
head: String,
2828
base: Branch,
2929
draft: Boolean
3030
)
31-
object PullRequestPayload {
32-
implicit val encoder: Encoder[PullRequestPayload] = deriveEncoder
31+
object CreatePullRequestPayload {
32+
implicit val encoder: Encoder[CreatePullRequestPayload] = deriveEncoder
3333

34-
def from(newPullRequestData: NewPullRequestData): PullRequestPayload =
35-
PullRequestPayload(
34+
def from(newPullRequestData: NewPullRequestData): CreatePullRequestPayload =
35+
CreatePullRequestPayload(
3636
title = newPullRequestData.title,
3737
body = newPullRequestData.body,
3838
head = newPullRequestData.head,

modules/core/src/main/scala/org/scalasteward/core/forge/github/GitHubApiAlg.scala

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,21 @@ final class GitHubApiAlg[F[_]](
3838
) extends ForgeApiAlg[F] {
3939
private val url = new Url(gitHubApiHost)
4040

41-
/** https://developer.github.com/v3/repos/forks/#create-a-fork */
41+
/** https://docs.github.com/en/rest/repos/forks?apiVersion=2022-11-28#create-a-fork */
4242
override def createFork(repo: Repo): F[RepoOut] =
4343
client.post[RepoOut](url.forks(repo), modify(repo)).flatTap { repoOut =>
4444
F.raiseWhen(repoOut.parent.exists(_.archived))(RepositoryArchived(repo))
4545
}
4646

47-
/** https://developer.github.com/v3/pulls/#create-a-pull-request */
47+
/** https://docs.github.com/en/rest/pulls?apiVersion=2022-11-28#create-a-pull-request */
4848
override def createPullRequest(repo: Repo, data: NewPullRequestData): F[PullRequestOut] = {
49-
val payload = PullRequestPayload.from(data)
49+
val payload = CreatePullRequestPayload.from(data)
5050
val create = client
51-
.postWithBody[PullRequestOut, PullRequestPayload](url.pulls(repo), payload, modify(repo))
51+
.postWithBody[PullRequestOut, CreatePullRequestPayload](
52+
uri = url.pulls(repo),
53+
body = payload,
54+
modify = modify(repo)
55+
)
5256
.adaptErr(SecondaryRateLimitExceeded.fromThrowable)
5357

5458
for {
@@ -61,29 +65,53 @@ final class GitHubApiAlg[F[_]](
6165
} yield pullRequestOut
6266
}
6367

64-
/** https://developer.github.com/v3/repos/branches/#get-branch */
68+
/** https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#update-a-pull-request */
69+
override def updatePullRequest(
70+
number: PullRequestNumber,
71+
repo: Repo,
72+
data: NewPullRequestData
73+
): F[Unit] = {
74+
val payload = UpdatePullRequestPayload.from(data)
75+
76+
val update = client
77+
.patchWithBody[PullRequestOut, UpdatePullRequestPayload](
78+
uri = url.pull(repo, number),
79+
body = payload,
80+
modify = modify(repo)
81+
)
82+
.adaptErr(SecondaryRateLimitExceeded.fromThrowable)
83+
84+
for {
85+
_ <- update
86+
_ <- F.whenA(data.labels.nonEmpty)(labelPullRequest(repo, number, data.labels))
87+
_ <- F.whenA(data.assignees.nonEmpty)(addAssignees(repo, number, data.assignees))
88+
_ <- F.whenA(data.reviewers.nonEmpty)(addReviewers(repo, number, data.reviewers))
89+
} yield ()
90+
}
91+
92+
/** https://docs.github.com/en/rest/repos/branches?apiVersion=2022-11-28#get-branch */
6593
override def getBranch(repo: Repo, branch: Branch): F[BranchOut] =
6694
client.get(url.branches(repo, branch), modify(repo))
6795

68-
/** https://developer.github.com/v3/repos/#get */
96+
/** https://docs.github.com/en/rest/repos?apiVersion=2022-11-28#get */
6997
override def getRepo(repo: Repo): F[RepoOut] =
7098
client.get[RepoOut](url.repos(repo), modify(repo)).flatTap { repoOut =>
7199
F.raiseWhen(repoOut.archived)(RepositoryArchived(repo))
72100
}
73101

74-
/** https://developer.github.com/v3/pulls/#list-pull-requests */
102+
/** https://docs.github.com/en/rest/pulls?apiVersion=2022-11-28#list-pull-requests */
75103
override def listPullRequests(repo: Repo, head: String, base: Branch): F[List[PullRequestOut]] =
76104
client.get(url.listPullRequests(repo, head, base), modify(repo))
77105

78-
/** https://developer.github.com/v3/pulls/#update-a-pull-request */
106+
/** https://docs.github.com/en/rest/pulls?apiVersion=2022-11-28#update-a-pull-request */
79107
override def closePullRequest(repo: Repo, number: PullRequestNumber): F[PullRequestOut] =
80108
client.patchWithBody[PullRequestOut, UpdateState](
81109
url.pull(repo, number),
82110
UpdateState(PullRequestState.Closed),
83111
modify(repo)
84112
)
85113

86-
/** https://developer.github.com/v3/issues#create-an-issue-comment */
114+
/** https://docs.github.com/en/rest/issues?apiVersion=2022-11-28#create-an-issue-comment */
87115
override def commentPullRequest(
88116
repo: Repo,
89117
number: PullRequestNumber,
@@ -92,7 +120,8 @@ final class GitHubApiAlg[F[_]](
92120
client
93121
.postWithBody(url.comments(repo, number), Comment(comment), modify(repo))
94122

95-
/** https://docs.github.com/en/rest/reference/issues#add-labels-to-an-issue */
123+
/** https://docs.github.com/en/rest/reference/issues?apiVersion=2022-11-28#add-labels-to-an-issue
124+
*/
96125
private def labelPullRequest(
97126
repo: Repo,
98127
number: PullRequestNumber,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2018-2023 Scala Steward contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.scalasteward.core.forge.github
18+
19+
import io.circe.Encoder
20+
import io.circe.generic.semiauto.deriveEncoder
21+
import org.scalasteward.core.forge.data.NewPullRequestData
22+
23+
final case class UpdatePullRequestPayload(
24+
title: String,
25+
body: String
26+
)
27+
object UpdatePullRequestPayload {
28+
implicit val encoder: Encoder[UpdatePullRequestPayload] = deriveEncoder
29+
30+
def from(newPullRequestData: NewPullRequestData): UpdatePullRequestPayload =
31+
UpdatePullRequestPayload(
32+
title = newPullRequestData.title,
33+
body = newPullRequestData.body
34+
)
35+
}

modules/core/src/main/scala/org/scalasteward/core/forge/gitlab/GitLabApiAlg.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ final class GitLabApiAlg[F[_]: Parallel](
248248
updatedMergeRequest.map(_.pullRequestOut)
249249
}
250250

251+
override def updatePullRequest(
252+
number: PullRequestNumber,
253+
repo: Repo,
254+
data: NewPullRequestData
255+
): F[Unit] =
256+
logger.warn("Updating PRs is not yet supported for GitLab")
257+
251258
private def mergePipelineUponSuccess(repo: Repo, mr: MergeRequestOut): F[MergeRequestOut] =
252259
mr match {
253260
case mr if mr.mergeStatus === GitLabMergeStatus.CanBeMerged =>

modules/core/src/main/scala/org/scalasteward/core/nurture/NurtureAlg.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package org.scalasteward.core.nurture
1818

1919
import cats.effect.Concurrent
20-
import cats.implicits._
20+
import cats.syntax.all._
2121
import cats.{Applicative, Id}
2222
import org.scalasteward.core.application.Config.ForgeCfg
2323
import org.scalasteward.core.coursier.CoursierAlg
@@ -99,7 +99,7 @@ final class NurtureAlg[F[_]](config: ForgeCfg)(implicit
9999
logger.info(s"PR ${pr.html_url} is closed") >>
100100
deleteRemoteBranch(data.repo, data.updateBranch).as(Ignored)
101101
case Some(pr) if !pr.state.isClosed =>
102-
logger.info(s"Found PR ${pr.html_url}") >> updatePullRequest(data)
102+
logger.info(s"Found PR ${pr.html_url}") >> updatePullRequest(data, pr.number)
103103
case _ =>
104104
applyNewUpdate(data).flatTap {
105105
case Created(newPrNumber) => closeObsoletePullRequests(data, newPrNumber)
@@ -262,14 +262,14 @@ final class NurtureAlg[F[_]](config: ForgeCfg)(implicit
262262
_ <- logger.info(s"Created PR ${pr.html_url}")
263263
} yield Created(pr.number)
264264

265-
private def updatePullRequest(data: UpdateData): F[ProcessResult] =
265+
private def updatePullRequest(data: UpdateData, number: PullRequestNumber): F[ProcessResult] =
266266
if (data.repoConfig.updatePullRequestsOrDefault =!= PullRequestUpdateStrategy.Never)
267267
gitAlg.returnToCurrentBranch(data.repo) {
268-
for {
269-
_ <- gitAlg.checkoutBranch(data.repo, data.updateBranch)
270-
update <- shouldBeUpdated(data)
271-
result <- if (update) mergeAndApplyAgain(data) else F.pure[ProcessResult](Ignored)
272-
} yield result
268+
gitAlg.checkoutBranch(data.repo, data.updateBranch) >>
269+
shouldBeUpdated(data).ifM(
270+
ifTrue = mergeAndApplyAgain(number, data),
271+
ifFalse = (Ignored: ProcessResult).pure
272+
)
273273
}
274274
else
275275
logger.info("PR updates are disabled by flag").as(Ignored)
@@ -293,7 +293,7 @@ final class NurtureAlg[F[_]](config: ForgeCfg)(implicit
293293
result.flatMap { case (update, msg) => logger.info(msg).as(update) }
294294
}
295295

296-
private def mergeAndApplyAgain(data: UpdateData): F[ProcessResult] =
296+
private def mergeAndApplyAgain(number: PullRequestNumber, data: UpdateData): F[ProcessResult] =
297297
for {
298298
_ <- logger.info(
299299
s"Merge branch ${data.baseBranch.name} into ${data.updateBranch.name} and apply again"
@@ -307,6 +307,8 @@ final class NurtureAlg[F[_]](config: ForgeCfg)(implicit
307307
editCommits = edits.flatMap(_.commits)
308308
commits = maybeRevertCommit.toList ++ maybeMergeCommit.toList ++ editCommits
309309
result <- pushCommits(data, commits)
310+
requestData <- preparePullRequest(data, edits)
311+
_ <- forgeApiAlg.updatePullRequest(number: PullRequestNumber, data.repo, requestData)
310312
} yield result
311313

312314
}

0 commit comments

Comments
 (0)