Skip to content

Commit 42eec29

Browse files
authored
Merge pull request #320 from Dwolla/mergify-actions
Add request_reviews and update Mergify actions
2 parents d642490 + 3ad097d commit 42eec29

File tree

3 files changed

+121
-3
lines changed

3 files changed

+121
-3
lines changed

.mergify.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
pull_request_rules:
99
- name: merge scala-steward's PRs
1010
conditions:
11-
- author=scala-steward
11+
- author=typelevel-steward[bot]
1212
- or:
1313
- body~=labels:.*early-semver-patch
1414
- body~=labels:.*early-semver-minor
@@ -168,3 +168,10 @@ pull_request_rules:
168168
add:
169169
- versioning
170170
remove: []
171+
- name: assign scala-steward's PRs for review
172+
conditions:
173+
- author=typelevel-steward[bot]
174+
actions:
175+
request_reviews:
176+
users:
177+
- armanbilge

build.sbt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,18 @@ ThisBuild / developers := List(
1111
tlGitHubDev("djspiewak", "Daniel Spiewak")
1212
)
1313

14-
ThisBuild / mergifyStewardConfig ~= { _.map(_.copy(mergeMinors = true)) }
14+
ThisBuild / mergifyStewardConfig ~= {
15+
_.map(_.copy(mergeMinors = true, author = "typelevel-steward[bot]"))
16+
}
1517
ThisBuild / mergifySuccessConditions += MergifyCondition.Custom("#approved-reviews-by>=1")
1618
ThisBuild / mergifyLabelPaths += { "docs" -> file("docs") }
19+
ThisBuild / mergifyPrRules += MergifyPrRule(
20+
"assign scala-steward's PRs for review",
21+
List(MergifyCondition.Custom("author=typelevel-steward[bot]")),
22+
List(
23+
MergifyAction.RequestReviews.fromUsers("armanbilge")
24+
)
25+
)
1726

1827
ThisBuild / scalafixDependencies ++= Seq(
1928
"com.github.liancheng" %% "organize-imports" % "0.6.0"

mergify/src/main/scala/org/typelevel/sbt/mergify/MergifyAction.scala

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616

1717
package org.typelevel.sbt.mergify
1818

19-
import io.circe.Encoder
19+
import cats.data._
20+
import cats.syntax.all._
21+
import io.circe._
2022
import io.circe.syntax._
23+
import org.typelevel.sbt.mergify.MergifyAction.RequestReviews._
24+
import sbt.librarymanagement.Developer
2125

2226
sealed abstract class MergifyAction {
2327
private[mergify] def name = getClass.getSimpleName.toLowerCase
@@ -28,6 +32,8 @@ object MergifyAction {
2832
implicit def encoder: Encoder[MergifyAction] = Encoder.instance {
2933
case merge: Merge => merge.asJson
3034
case label: Label => label.asJson
35+
case requestReviews: RequestReviews => requestReviews.asJson
36+
case Update => Update.asJson
3137
case _ => sys.error("should not happen")
3238
}
3339

@@ -57,6 +63,102 @@ object MergifyAction {
5763
}
5864
}
5965

66+
class RequestReviews private (
67+
private val users: Option[OptionallyWeighted],
68+
private val teams: Option[OptionallyWeighted],
69+
private val usersFromTeams: Option[OptionallyWeighted],
70+
private val randomCount: Option[Int])
71+
extends MergifyAction {
72+
override private[mergify] def name = "request_reviews"
73+
74+
private def copy(
75+
users: Option[OptionallyWeighted] = users,
76+
teams: Option[OptionallyWeighted] = teams,
77+
usersFromTeams: Option[OptionallyWeighted] = usersFromTeams,
78+
randomCount: Option[Int] = randomCount): RequestReviews =
79+
new RequestReviews(users, teams, usersFromTeams, randomCount) {}
80+
81+
def withUsers(user: String, users: String*): RequestReviews =
82+
copy(users = Unweighted(NonEmptyList.of(user, users: _*)).some)
83+
84+
def withUsers(user: (String, Int), users: (String, Int)*): RequestReviews =
85+
copy(users = Weighted(NonEmptyList.of(user, users: _*)).some)
86+
87+
def withTeams(team: String, teams: String*): RequestReviews =
88+
copy(teams = Unweighted(NonEmptyList.of(team, teams: _*)).some)
89+
90+
def withTeams(team: (String, Int), teams: (String, Int)*): RequestReviews =
91+
copy(teams = Weighted(NonEmptyList.of(team, teams: _*)).some)
92+
93+
def withUsersFromTeams(team: String, teams: String*): RequestReviews =
94+
copy(usersFromTeams = Unweighted(NonEmptyList.of(team, teams: _*)).some)
95+
96+
def withUsersFromTeams(team: (String, Int), teams: (String, Int)*): RequestReviews =
97+
copy(usersFromTeams = Weighted(NonEmptyList.of(team, teams: _*)).some)
98+
99+
def withRandomCount(count: Int): RequestReviews =
100+
copy(randomCount = Option(count))
101+
102+
def withDevelopers(developers: List[Developer]): RequestReviews =
103+
copy(users = NonEmptyList.fromList(developers.map(_.id)).map(Unweighted))
104+
}
105+
106+
object RequestReviews {
107+
def fromUsers(user: String, users: String*) =
108+
new RequestReviews(Unweighted(NonEmptyList.of(user, users: _*)).some, None, None, None)
109+
def fromUsers(user: (String, Int), users: (String, Int)*) =
110+
new RequestReviews(Weighted(NonEmptyList.of(user, users: _*)).some, None, None, None)
111+
def fromTeams(team: String, teams: String*) =
112+
new RequestReviews(None, Unweighted(NonEmptyList.of(team, teams: _*)).some, None, None)
113+
def fromTeams(team: (String, Int), teams: (String, Int)*) =
114+
new RequestReviews(None, Weighted(NonEmptyList.of(team, teams: _*)).some, None, None)
115+
def fromUsersOfTeams(team: String, teams: String*) =
116+
new RequestReviews(None, None, Unweighted(NonEmptyList.of(team, teams: _*)).some, None)
117+
def fromUsersOfTeams(team: (String, Int), teams: (String, Int)*) =
118+
new RequestReviews(None, None, Weighted(NonEmptyList.of(team, teams: _*)).some, None)
119+
120+
def apply(developers: List[Developer]) =
121+
new RequestReviews(
122+
Unweighted(
123+
developers
124+
.map(_.id)
125+
.toNel
126+
.getOrElse(throw new RuntimeException("developers must be non-empty"))
127+
).some,
128+
None,
129+
None,
130+
None)
131+
132+
implicit def encoder: Encoder[RequestReviews] =
133+
Encoder.forProduct4("users", "teams", "users_from_teams", "random_count") {
134+
requestReviews =>
135+
(
136+
requestReviews.users,
137+
requestReviews.teams,
138+
requestReviews.usersFromTeams,
139+
requestReviews.randomCount
140+
)
141+
}
142+
143+
private sealed trait OptionallyWeighted
144+
private case class Weighted(value: NonEmptyList[(String, Int)]) extends OptionallyWeighted
145+
private case class Unweighted(value: NonEmptyList[String]) extends OptionallyWeighted
146+
147+
private object OptionallyWeighted {
148+
implicit val encoder: Encoder[OptionallyWeighted] = {
149+
case Weighted(value) => value.asJson
150+
case Unweighted(value) => value.asJson
151+
}
152+
}
153+
}
154+
155+
object Update extends MergifyAction {
156+
override private[mergify] def name = "update"
157+
158+
implicit def encoder: Encoder[Update.type] =
159+
Encoder[JsonObject].contramap(_ => JsonObject.empty)
160+
}
161+
60162
private[this] object Dummy extends MergifyAction
61163

62164
}

0 commit comments

Comments
 (0)