Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin to maintain .mergify.yml #46

Open
nafg opened this issue Dec 28, 2020 · 10 comments
Open

Plugin to maintain .mergify.yml #46

nafg opened this issue Dec 28, 2020 · 10 comments

Comments

@nafg
Copy link

nafg commented Dec 28, 2020

As a possible alternative to #39, would there be any interest in something like the following rough draft? Basically it keeps the jobs in .mergify.yml up to date when running githubWorkflowGenerate:

import java.io.{File, FileInputStream}
import java.{util => ju}

import scala.collection.JavaConverters._
import scala.util.matching.Regex

import org.yaml.snakeyaml.Yaml
import sbt.AutoPlugin
import sbt.io.IO
import sbtghactions.GenerativeKeys.{githubWorkflowGenerate, githubWorkflowGeneratedCI}
import sbtghactions.GenerativePlugin


object Mergify extends AutoPlugin {
  override def requires = GenerativePlugin
  override def trigger = allRequirements

  type Dict = ju.Map[String, AnyRef]

  override def projectSettings = Seq(
    githubWorkflowGenerate := {
      githubWorkflowGenerate.value
      githubWorkflowGeneratedCI.value
        .find(_.id == "build")
        .foreach { job =>
          val yaml = new Yaml
          val res = yaml.load[Dict](new FileInputStream(".mergify.yml"))
          val conditions =
            res
              .get("pull_request_rules").asInstanceOf[ju.List[Dict]].asScala.map(_.asScala)
              .find(_ ("name") == "Automatically merge successful scala-steward PRs").get
              .apply("conditions").asInstanceOf[ju.List[String]].asScala

          val existing = conditions.filter(_.matches(s"status-success=${Regex.quote(job.name)} \\(.*\\)"))
          conditions --= existing

          val concreteJobNames = for (o <- job.oses; s <- job.scalas; v <- job.javas) yield s"${job.name} ($o, $s, $v)"

          conditions ++= concreteJobNames.map(name => s"status-success=$name")

          IO.write(new File(".mergify.yml"), yaml.dumpAsMap(res))
        }
    }
  )
}
@djspiewak
Copy link
Collaborator

This is a really really interesting idea! Particularly since we can make it work nicely with scala-steward and such in the very common case. Is it best to have something like that organizationally within this plugin, or is it better to distribute it separately (e.g. sbt-mergify)?

@jatcwang
Copy link

jatcwang commented Feb 7, 2021

Having it as part of sbt-github-actions initially will be less work / faster to iterate I think. Can always split it out if there's demand but I suspect that most OSS projects will be using both GHA and mergify

@djspiewak
Copy link
Collaborator

Okay I'm definitely convinced that this is worth doing. I'd be fine with either having it here or in a separate project which depends on this one.

@nafg
Copy link
Author

nafg commented Mar 7, 2021

If people want my sloppy version I would be very happy if someone can tell me the quickest way to publish it somewhere people can use it.

To make a more principled version we first need some sort of behavior spec.

@nafg
Copy link
Author

nafg commented Mar 7, 2021

(once that's coded up it may be worthy of being included here.)

@nafg
Copy link
Author

nafg commented Mar 15, 2021

Today I've been working on a library to generate Mergify files in a principled manner. I haven't written a DSL yet so code looks like this right now:

  val data =
    Mergify(
      pullRequestRules =
        List(
          PullRequestRule(
            name = "automatic merge successful scala-steward PRs",
            conditions =
              List(
                Condition(Attribute.Author, Some(Operator.Equal -> "scala-steward")),
                Condition(Attribute.CheckSuccess, Some(Operator.Equal -> "Travis CI - Pull Request"))
              ),
            actions =
              ActionSet(
                List(
                  Action.Merge(
                    strict = Some(Json.fromBoolean(true))
                  )
                )
              )
          )
        )
    )

@nafg
Copy link
Author

nafg commented Mar 15, 2021

Now available:

    resolvers += "jitpack" at "https://jitpack.io"
    libraryDependencies += "com.github.nafg" % "mergify-yaml" % "0.1.0"

Currently it is only built for scala 2.12 because my use case is in sbt builds.

Demo: https://github.com/nafg/mergify-yaml/blob/master/src/test/scala/io/github/nafg/mergify/Demo.scala

@nafg
Copy link
Author

nafg commented Mar 15, 2021

With a DSL published in 0.2.0, my original code (that I started this issue with) can be replaced with:

import io.github.nafg.mergify.dsl._

import sbt._
import sbtghactions.GenerativePlugin
import sbtghactions.GenerativePlugin.autoImport._


object WriteMergify extends AutoPlugin {
  override def requires = GenerativePlugin
  override def trigger = allRequirements
  override def projectSettings = Seq(
    githubWorkflowGenerate := {
      githubWorkflowGenerate.value
      for (job <- githubWorkflowGeneratedCI.value if job.id == "build")
        IO.write(
          file(".mergify.yml"),
          mergify
            .withRule("Automatically merge successful scala-steward PRs")(
              (Attr.Author :== "scala-steward") +:
                (for (o <- job.oses; s <- job.scalas; v <- job.javas) yield
                  Attr.CheckSuccess :== s"${job.name} ($o, $s, $v)"): _*
            )(Action.Merge(strict = true))
            .toYaml
        )
    }
  )
}

It would be nice if I didn't have to generate the matrix job names myself, not to mention comparing the job id to a magic string. If those were provided by this plugin, the code would be even shorter.

@nafg
Copy link
Author

nafg commented Mar 19, 2021

It's now on maven central, so

- resolvers += "jitpack" at "https://jitpack.io"
- libraryDependencies += "com.github.nafg" % "mergify-yaml" % "0.1.0"
+ libraryDependencies += "io.github.nafg.mergify" %% "mergify-writer" % "0.2.1"

@nafg
Copy link
Author

nafg commented Dec 19, 2021

The snippet in #46 (comment) is no longer valid in 0.14.x: $v needs to be changed to ${v.render}.

Since it doesn't seem like it will be integrated into this plugin, I've now published the updated snippet as its own sbt plugin. To use it I'm applying the following change:

diff --git a/project/WriteMergify.scala b/project/WriteMergify.scala
deleted file mode 100644
index f99df17..0000000
--- a/project/WriteMergify.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-import io.github.nafg.mergify.dsl._
-import sbt._
-import sbtghactions.GenerativePlugin
-import sbtghactions.GenerativePlugin.autoImport._
-
-
-object WriteMergify extends AutoPlugin {
-  override def requires = GenerativePlugin
-
-  override def trigger = allRequirements
-
-  override def projectSettings = Seq(
-    githubWorkflowGenerate := {
-      githubWorkflowGenerate.value
-      for (job <- githubWorkflowGeneratedCI.value if job.id == "build")
-        IO.write(
-          file(".mergify.yml"),
-          mergify
-            .withRule("Automatically merge successful scala-steward PRs")(
-              (Attr.Author :== "scala-steward") +:
-                (for (o <- job.oses; s <- job.scalas; v <- job.javas) yield
-                  Attr.CheckSuccess :== s"${job.name} ($o, $s, $v)"): _*
-            )(Action.Merge(strict = true))
-            .toYaml
-        )
-    }
-  )
-}
diff --git a/project/build-build.sbt b/project/build-build.sbt
index e60bce8..e7a4bfa 100644
--- a/project/build-build.sbt
+++ b/project/build-build.sbt
@@ -1,2 +1 @@
 libraryDependencies += "org.jsoup" % "jsoup" % "1.14.3"
-libraryDependencies += "io.github.nafg.mergify" %% "mergify-writer" % "0.3.0"
diff --git a/project/plugins.sbt b/project/plugins.sbt
index cf9fab0..1ad8c6d 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,2 +1,2 @@
 addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10")
-addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.13.0")
+addSbtPlugin("io.github.nafg.mergify" % "sbt-mergify-github-actions" % "0.3.0")

You may need to run sbt githubWorkflowGenerate, of course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants