Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ jobs:

- name: Make target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/series/0.4')
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
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

- name: Compress target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/series/0.4')
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
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

- name: Upload target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/series/0.4')
Expand Down
154 changes: 154 additions & 0 deletions .mergify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# This file was automatically generated by sbt-typelevel-mergify using the
# mergifyGenerate task. You should add and commit this file to
# your git repository. It goes without saying that you shouldn't edit
# this file by hand! Instead, if you wish to make changes, you should
# change your sbt build configuration to revise the mergify configuration
# to meet your needs, then regenerate this file.

pull_request_rules:
- name: merge scala-steward's PRs
conditions:
- author=scala-steward
- or:
- body~=labels:.*early-semver-patch
- body~=labels:.*early-semver-minor
- status-success=Build and Test (ubuntu-latest, 2.12.15, temurin@8, rootJVM)
- '#approved-reviews-by>=1'
Comment on lines +9 to +16

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fthomas if you have a chance, would appreciate your eyes on this. Are these labels the right configuration for checking steward PRs? Thanks! :)

actions:
merge: {}
- name: Label ci PRs
conditions:
- files~=^ci/
actions:
label:
add:
- ci
remove: []
- name: Label ci-release PRs
conditions:
- files~=^ci-release/
actions:
label:
add:
- ci-release
remove: []
- name: Label ci-signing PRs
conditions:
- files~=^ci-signing/
actions:
label:
add:
- ci-signing
remove: []
- name: Label core PRs
conditions:
- files~=^core/
actions:
label:
add:
- core
remove: []
- name: Label docs PRs
conditions:
- files~=^docs/
actions:
label:
add:
- docs
remove: []
- name: Label github PRs
conditions:
- files~=^github/
actions:
label:
add:
- github
remove: []
- name: Label github-actions PRs
conditions:
- files~=^github-actions/
actions:
label:
add:
- github-actions
remove: []
- name: Label kernel PRs
conditions:
- files~=^kernel/
actions:
label:
add:
- kernel
remove: []
- name: Label mdocs PRs
conditions:
- files~=^mdocs/
actions:
label:
add:
- mdocs
remove: []
- name: Label mergify PRs
conditions:
- files~=^mergify/
actions:
label:
add:
- mergify
remove: []
- name: Label mima PRs
conditions:
- files~=^mima/
actions:
label:
add:
- mima
remove: []
- name: Label no-publish PRs
conditions:
- files~=^no-publish/
actions:
label:
add:
- no-publish
remove: []
- name: Label settings PRs
conditions:
- files~=^settings/
actions:
label:
add:
- settings
remove: []
- name: Label site PRs
conditions:
- files~=^site/
actions:
label:
add:
- site
remove: []
- name: Label sonatype PRs
conditions:
- files~=^sonatype/
actions:
label:
add:
- sonatype
remove: []
- name: Label sonatype-ci-release PRs
conditions:
- files~=^sonatype-ci-release/
actions:
label:
add:
- sonatype-ci-release
remove: []
- name: Label versioning PRs
conditions:
- files~=^versioning/
actions:
label:
add:
- versioning
remove: []
14 changes: 14 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ ThisBuild / developers := List(
tlGitHubDev("djspiewak", "Daniel Spiewak")
)

ThisBuild / mergifyStewardConfig ~= { _.map(_.copy(mergeMinors = true)) }
ThisBuild / mergifySuccessConditions += MergifyCondition.Custom("#approved-reviews-by>=1")
Comment on lines +14 to +15

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mergeMinors, because I'm dog-fooding. But I actually don't trust any update to upstream sbt plugins is not going to break things, patch or not ...

ThisBuild / mergifyLabelPaths += { "docs" -> file("docs") }

lazy val root = tlCrossRootProject.aggregate(
kernel,
noPublish,
settings,
github,
githubActions,
mergify,
versioning,
mima,
sonatype,
Expand Down Expand Up @@ -66,6 +71,15 @@ lazy val githubActions = project
name := "sbt-typelevel-github-actions"
)

lazy val mergify = project
.in(file("mergify"))
.enablePlugins(SbtPlugin)
.settings(
name := "sbt-typelevel-mergify",
tlVersionIntroduced := Map("2.12" -> "0.4.6")
)
.dependsOn(githubActions)

lazy val versioning = project
.in(file("versioning"))
.enablePlugins(SbtPlugin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ ${indent(jobs.map(compileJob(_, sbt)).mkString("\n\n"), 1)}
githubWorkflowGeneratedDownloadSteps := {
val extraKeys = githubWorkflowArtifactDownloadExtraKeys.value
val additions = githubWorkflowBuildMatrixAdditions.value
val matrix = additions.map {
val matrixAdds = additions.map {
case (key, values) =>
if (extraKeys(key))
key -> values // we want to iterate over all values
Expand All @@ -615,25 +615,23 @@ ${indent(jobs.map(compileJob(_, sbt)).mkString("\n\n"), 1)}
}

val keys = "scala" :: additions.keys.toList.sorted
val oses = githubWorkflowOSes.value.toList
val scalas = githubWorkflowScalaVersions.value.toList
val exclusions = githubWorkflowBuildMatrixExclusions.value
val javas = githubWorkflowJavaVersions.value.toList
val exclusions = githubWorkflowBuildMatrixExclusions.value.toList

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

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

private[gha] def diff(expected: String, actual: String): String = {
private[sbt] def expandMatrix(
oses: List[String],
scalas: List[String],
javas: List[JavaSpec],
matrixAdds: Map[String, List[String]],
includes: List[MatrixInclude],
excludes: List[MatrixExclude]
): List[List[String]] = {
val keys = "os" :: "scala" :: "java" :: matrixAdds.keys.toList.sorted
val matrix =
matrixAdds + ("os" -> oses) + ("scala" -> scalas) + ("java" -> javas.map(_.render))

// expand the matrix
keys
.foldLeft(List(List.empty[String])) { (cells, key) =>
val values = matrix.getOrElse(key, Nil)
cells.flatMap { cell => values.map(v => cell ::: v :: Nil) }
}
.filterNot { cell => // remove the excludes
val job = keys.zip(cell).toMap
excludes.exists { // there is an exclude that matches the current job
case MatrixExclude(matching) => matching.toSet.subsetOf(job.toSet)
}
} ::: includes.map { // add the includes
case MatrixInclude(matching, additions) =>
// yoloing here, but let's wait for the bug report
keys.map(matching) ::: additions.values.toList
}
}

private[sbt] def diff(expected: String, actual: String): String = {
val expectedLines = expected.split("\n", -1)
val actualLines = actual.split("\n", -1)
val (lines, _) =
Expand Down
1 change: 1 addition & 0 deletions mergify/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
libraryDependencies += "io.circe" %% "circe-yaml" % "0.14.1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2022 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.typelevel.sbt.mergify

import io.circe.Encoder
import io.circe.syntax._

sealed abstract class MergifyAction {
private[mergify] def name = getClass.getSimpleName.toLowerCase
}

object MergifyAction {

implicit def encoder: Encoder[MergifyAction] = Encoder.instance {
case merge: Merge => merge.asJson
case label: Label => label.asJson
case _ => sys.error("should not happen")
}

final case class Merge(
method: Option[String] = None,
rebaseFallback: Option[String] = None,
commitMessageTemplate: Option[String] = None
) extends MergifyAction

object Merge {
implicit def encoder: Encoder[Merge] =
Encoder.forProduct3("method", "rebase_fallback", "commit_message_template") {
(m: Merge) => (m.method, m.rebaseFallback, m.commitMessageTemplate)
}
}

final case class Label(
add: List[String] = Nil,
remove: List[String] = Nil,
removeAll: Option[Boolean] = None
) extends MergifyAction

object Label {
implicit def encoder: Encoder[Label] =
Encoder.forProduct3("add", "remove", "remove_all") { (l: Label) =>
(l.add, l.remove, l.removeAll)
}
}

private[this] object Dummy extends MergifyAction

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trick lets us keep MergifyAction sealed while being able to compatibly add additional cases to the ADT, since users will never be able to exhaustively pattern match.


}
Loading