Skip to content

Commit 2113388

Browse files
authored
Merge pull request #190 from armanbilge/feature/mergify
Add plugin for generating `.mergify.yml` config
2 parents 49a72ce + 9843119 commit 2113388

File tree

12 files changed

+597
-20
lines changed

12 files changed

+597
-20
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ jobs:
8686

8787
- name: Make target directories
8888
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/series/0.4')
89-
run: mkdir -p github/target github-actions/target kernel/target versioning/target ci-release/target target .js/target mdocs/target site/target ci-signing/target mima/target .jvm/target .native/target no-publish/target sonatype/target ci/target sonatype-ci-release/target core/target settings/target project/target
89+
run: mkdir -p github/target github-actions/target kernel/target versioning/target ci-release/target target .js/target mdocs/target site/target ci-signing/target mergify/target mima/target .jvm/target .native/target no-publish/target sonatype/target ci/target sonatype-ci-release/target core/target settings/target project/target
9090

9191
- name: Compress target directories
9292
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/series/0.4')
93-
run: tar cf targets.tar github/target github-actions/target kernel/target versioning/target ci-release/target target .js/target mdocs/target site/target ci-signing/target mima/target .jvm/target .native/target no-publish/target sonatype/target ci/target sonatype-ci-release/target core/target settings/target project/target
93+
run: tar cf targets.tar github/target github-actions/target kernel/target versioning/target ci-release/target target .js/target mdocs/target site/target ci-signing/target mergify/target mima/target .jvm/target .native/target no-publish/target sonatype/target ci/target sonatype-ci-release/target core/target settings/target project/target
9494

9595
- name: Upload target directories
9696
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/series/0.4')

.mergify.yml

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# This file was automatically generated by sbt-typelevel-mergify using the
2+
# mergifyGenerate task. You should add and commit this file to
3+
# your git repository. It goes without saying that you shouldn't edit
4+
# this file by hand! Instead, if you wish to make changes, you should
5+
# change your sbt build configuration to revise the mergify configuration
6+
# to meet your needs, then regenerate this file.
7+
8+
pull_request_rules:
9+
- name: merge scala-steward's PRs
10+
conditions:
11+
- author=scala-steward
12+
- or:
13+
- body~=labels:.*early-semver-patch
14+
- body~=labels:.*early-semver-minor
15+
- status-success=Build and Test (ubuntu-latest, 2.12.15, temurin@8, rootJVM)
16+
- '#approved-reviews-by>=1'
17+
actions:
18+
merge: {}
19+
- name: Label ci PRs
20+
conditions:
21+
- files~=^ci/
22+
actions:
23+
label:
24+
add:
25+
- ci
26+
remove: []
27+
- name: Label ci-release PRs
28+
conditions:
29+
- files~=^ci-release/
30+
actions:
31+
label:
32+
add:
33+
- ci-release
34+
remove: []
35+
- name: Label ci-signing PRs
36+
conditions:
37+
- files~=^ci-signing/
38+
actions:
39+
label:
40+
add:
41+
- ci-signing
42+
remove: []
43+
- name: Label core PRs
44+
conditions:
45+
- files~=^core/
46+
actions:
47+
label:
48+
add:
49+
- core
50+
remove: []
51+
- name: Label docs PRs
52+
conditions:
53+
- files~=^docs/
54+
actions:
55+
label:
56+
add:
57+
- docs
58+
remove: []
59+
- name: Label github PRs
60+
conditions:
61+
- files~=^github/
62+
actions:
63+
label:
64+
add:
65+
- github
66+
remove: []
67+
- name: Label github-actions PRs
68+
conditions:
69+
- files~=^github-actions/
70+
actions:
71+
label:
72+
add:
73+
- github-actions
74+
remove: []
75+
- name: Label kernel PRs
76+
conditions:
77+
- files~=^kernel/
78+
actions:
79+
label:
80+
add:
81+
- kernel
82+
remove: []
83+
- name: Label mdocs PRs
84+
conditions:
85+
- files~=^mdocs/
86+
actions:
87+
label:
88+
add:
89+
- mdocs
90+
remove: []
91+
- name: Label mergify PRs
92+
conditions:
93+
- files~=^mergify/
94+
actions:
95+
label:
96+
add:
97+
- mergify
98+
remove: []
99+
- name: Label mima PRs
100+
conditions:
101+
- files~=^mima/
102+
actions:
103+
label:
104+
add:
105+
- mima
106+
remove: []
107+
- name: Label no-publish PRs
108+
conditions:
109+
- files~=^no-publish/
110+
actions:
111+
label:
112+
add:
113+
- no-publish
114+
remove: []
115+
- name: Label settings PRs
116+
conditions:
117+
- files~=^settings/
118+
actions:
119+
label:
120+
add:
121+
- settings
122+
remove: []
123+
- name: Label site PRs
124+
conditions:
125+
- files~=^site/
126+
actions:
127+
label:
128+
add:
129+
- site
130+
remove: []
131+
- name: Label sonatype PRs
132+
conditions:
133+
- files~=^sonatype/
134+
actions:
135+
label:
136+
add:
137+
- sonatype
138+
remove: []
139+
- name: Label sonatype-ci-release PRs
140+
conditions:
141+
- files~=^sonatype-ci-release/
142+
actions:
143+
label:
144+
add:
145+
- sonatype-ci-release
146+
remove: []
147+
- name: Label versioning PRs
148+
conditions:
149+
- files~=^versioning/
150+
actions:
151+
label:
152+
add:
153+
- versioning
154+
remove: []

build.sbt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,17 @@ ThisBuild / developers := List(
1111
tlGitHubDev("djspiewak", "Daniel Spiewak")
1212
)
1313

14+
ThisBuild / mergifyStewardConfig ~= { _.map(_.copy(mergeMinors = true)) }
15+
ThisBuild / mergifySuccessConditions += MergifyCondition.Custom("#approved-reviews-by>=1")
16+
ThisBuild / mergifyLabelPaths += { "docs" -> file("docs") }
17+
1418
lazy val root = tlCrossRootProject.aggregate(
1519
kernel,
1620
noPublish,
1721
settings,
1822
github,
1923
githubActions,
24+
mergify,
2025
versioning,
2126
mima,
2227
sonatype,
@@ -66,6 +71,15 @@ lazy val githubActions = project
6671
name := "sbt-typelevel-github-actions"
6772
)
6873

74+
lazy val mergify = project
75+
.in(file("mergify"))
76+
.enablePlugins(SbtPlugin)
77+
.settings(
78+
name := "sbt-typelevel-mergify",
79+
tlVersionIntroduced := Map("2.12" -> "0.4.6")
80+
)
81+
.dependsOn(githubActions)
82+
6983
lazy val versioning = project
7084
.in(file("versioning"))
7185
.enablePlugins(SbtPlugin)

github-actions/src/main/scala/org/typelevel/sbt/gha/GenerativePlugin.scala

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ ${indent(jobs.map(compileJob(_, sbt)).mkString("\n\n"), 1)}
606606
githubWorkflowGeneratedDownloadSteps := {
607607
val extraKeys = githubWorkflowArtifactDownloadExtraKeys.value
608608
val additions = githubWorkflowBuildMatrixAdditions.value
609-
val matrix = additions.map {
609+
val matrixAdds = additions.map {
610610
case (key, values) =>
611611
if (extraKeys(key))
612612
key -> values // we want to iterate over all values
@@ -615,25 +615,23 @@ ${indent(jobs.map(compileJob(_, sbt)).mkString("\n\n"), 1)}
615615
}
616616

617617
val keys = "scala" :: additions.keys.toList.sorted
618+
val oses = githubWorkflowOSes.value.toList
618619
val scalas = githubWorkflowScalaVersions.value.toList
619-
val exclusions = githubWorkflowBuildMatrixExclusions.value
620+
val javas = githubWorkflowJavaVersions.value.toList
621+
val exclusions = githubWorkflowBuildMatrixExclusions.value.toList
620622

621623
// we build the list of artifacts, by iterating over all combinations of keys
622-
val artifacts = matrix
623-
.toList
624-
.sortBy(_._1)
625-
.map(_._2)
626-
.foldLeft(scalas.map(List(_))) { (artifacts, values) =>
627-
for {
628-
artifact <- artifacts
629-
value <- values
630-
} yield artifact :+ value
631-
} // then, we filter artifacts for keys that are excluded from the matrix
632-
.filterNot { artifact =>
633-
val job = keys.zip(artifact).toMap
634-
exclusions.exists { // there is an exclude that matches the current job
635-
case MatrixExclude(matching) => matching.toSet.subsetOf(job.toSet)
636-
}
624+
val artifacts =
625+
expandMatrix(
626+
oses,
627+
scalas,
628+
javas,
629+
matrixAdds,
630+
Nil,
631+
exclusions
632+
).map {
633+
case _ :: scala :: _ :: tail => scala :: tail
634+
case _ => sys.error("Bug generating artifact download steps") // shouldn't happen
637635
}
638636

639637
if (githubWorkflowArtifactUpload.value) {
@@ -862,7 +860,37 @@ ${indent(jobs.map(compileJob(_, sbt)).mkString("\n\n"), 1)}
862860
}
863861
)
864862

865-
private[gha] def diff(expected: String, actual: String): String = {
863+
private[sbt] def expandMatrix(
864+
oses: List[String],
865+
scalas: List[String],
866+
javas: List[JavaSpec],
867+
matrixAdds: Map[String, List[String]],
868+
includes: List[MatrixInclude],
869+
excludes: List[MatrixExclude]
870+
): List[List[String]] = {
871+
val keys = "os" :: "scala" :: "java" :: matrixAdds.keys.toList.sorted
872+
val matrix =
873+
matrixAdds + ("os" -> oses) + ("scala" -> scalas) + ("java" -> javas.map(_.render))
874+
875+
// expand the matrix
876+
keys
877+
.foldLeft(List(List.empty[String])) { (cells, key) =>
878+
val values = matrix.getOrElse(key, Nil)
879+
cells.flatMap { cell => values.map(v => cell ::: v :: Nil) }
880+
}
881+
.filterNot { cell => // remove the excludes
882+
val job = keys.zip(cell).toMap
883+
excludes.exists { // there is an exclude that matches the current job
884+
case MatrixExclude(matching) => matching.toSet.subsetOf(job.toSet)
885+
}
886+
} ::: includes.map { // add the includes
887+
case MatrixInclude(matching, additions) =>
888+
// yoloing here, but let's wait for the bug report
889+
keys.map(matching) ::: additions.values.toList
890+
}
891+
}
892+
893+
private[sbt] def diff(expected: String, actual: String): String = {
866894
val expectedLines = expected.split("\n", -1)
867895
val actualLines = actual.split("\n", -1)
868896
val (lines, _) =

mergify/build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
libraryDependencies += "io.circe" %% "circe-yaml" % "0.14.1"
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2022 Typelevel
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.typelevel.sbt.mergify
18+
19+
import io.circe.Encoder
20+
import io.circe.syntax._
21+
22+
sealed abstract class MergifyAction {
23+
private[mergify] def name = getClass.getSimpleName.toLowerCase
24+
}
25+
26+
object MergifyAction {
27+
28+
implicit def encoder: Encoder[MergifyAction] = Encoder.instance {
29+
case merge: Merge => merge.asJson
30+
case label: Label => label.asJson
31+
case _ => sys.error("should not happen")
32+
}
33+
34+
final case class Merge(
35+
method: Option[String] = None,
36+
rebaseFallback: Option[String] = None,
37+
commitMessageTemplate: Option[String] = None
38+
) extends MergifyAction
39+
40+
object Merge {
41+
implicit def encoder: Encoder[Merge] =
42+
Encoder.forProduct3("method", "rebase_fallback", "commit_message_template") {
43+
(m: Merge) => (m.method, m.rebaseFallback, m.commitMessageTemplate)
44+
}
45+
}
46+
47+
final case class Label(
48+
add: List[String] = Nil,
49+
remove: List[String] = Nil,
50+
removeAll: Option[Boolean] = None
51+
) extends MergifyAction
52+
53+
object Label {
54+
implicit def encoder: Encoder[Label] =
55+
Encoder.forProduct3("add", "remove", "remove_all") { (l: Label) =>
56+
(l.add, l.remove, l.removeAll)
57+
}
58+
}
59+
60+
private[this] object Dummy extends MergifyAction
61+
62+
}

0 commit comments

Comments
 (0)