diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1582763d8..6bdf078ee8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,6 +52,31 @@ This is the process for committing code into master. There are of course excepti 9. Once everything is said and done, associate the ticket with the “earliest” release milestone (i.e. if back-ported so that it will be in release x.y.z, find the relevant milestone for that release) and close it. +## The `validatePullRequest` task + +The Akka build includes a special task called `validatePullRequest` which investigates the changes made as well as dirty +(uncommitted changes) in your local working directory and figures out which projects are impacted by those changes, +then running tests only on those projects. + +For example changing something in `akka-http-core` would cause tests to be run in all projects which depend on it +(e.g. `akka-http-core-tests`, `akka-http-marshallers-*`, `akka-docs` etc.). + +To use the task simply type, and the output should include entries like shown below: + +``` +> validatePullRequest +[info] Diffing [HEAD] to determine changed modules in PR... +[info] Detected uncomitted changes in directories (including in dependency analysis): [akka-protobuf,project] +[info] Detected changes in directories: [akka-docs, project, akka-http-tests, akka-protobuf, akka-http-testkit, akka-http, akka-http-core, akka-stream] +``` + +By default changes are diffed with the `master` branch when working locally, if you want to validate against a different +target PR branch you can do so by setting the PR_TARGET_BRANCH environment variable for SBT: + +``` +PR_TARGET_BRANCH=origin/example sbt validatePullRequest +``` + ## Pull Request Requirements For a Pull Request to be considered at all it has to meet these requirements: diff --git a/akka-protobuf/build.sbt b/akka-protobuf/build.sbt index 0447129b55..d304a329c0 100644 --- a/akka-protobuf/build.sbt +++ b/akka-protobuf/build.sbt @@ -1,4 +1,5 @@ import akka.{ AkkaBuild, Formatting, OSGi, Unidoc, Dependencies } + import com.typesafe.tools.mima.plugin.MimaKeys AkkaBuild.defaultSettings diff --git a/project/ValidatePullRequest.scala b/project/ValidatePullRequest.scala index 78fcd607e5..2d798e1cc5 100644 --- a/project/ValidatePullRequest.scala +++ b/project/ValidatePullRequest.scala @@ -65,6 +65,8 @@ object ValidatePullRequest extends AutoPlugin { val SourcePullIdJenkinsEnvVarName = "ghprbPullId" // used to obtain branch name in form of "pullreq/17397" val sourceBranch = settingKey[String]("Branch containing the changes of this PR") + val targetBranch = settingKey[String]("Target branch of this PR, defaults to `master`") + // asking github comments if this PR should be PLS BUILD ALL val githubEnforcedBuildAll = taskKey[Option[BuildMode]]("Checks via GitHub API if comments included the PLS BUILD ALL keyword") val buildAllKeyword = taskKey[Regex]("Magic phrase to be used to trigger building of the entire project instead of analysing dependencies") @@ -97,6 +99,11 @@ object ValidatePullRequest extends AutoPlugin { } } + def localTargetBranch: Option[String] = sys.env.get("PR_TARGET_BRANCH") + def jenkinsTargetBranch: Option[String] = sys.env.get("ghprbTargetBranch") + def runningOnJenkins: Boolean = jenkinsTargetBranch.isDefined + def runningLocally: Boolean = !runningOnJenkins + override lazy val buildSettings = Seq( sourceBranch in Global in ValidatePR := { sys.env.get(SourceBranchEnvVarName) orElse @@ -104,6 +111,14 @@ object ValidatePullRequest extends AutoPlugin { "HEAD" }, + targetBranch in Global in ValidatePR := { + (localTargetBranch, jenkinsTargetBranch) match { + case (Some(local), _) => local // local override + case (None, Some(branch)) => s"origin/$branch" // usually would be "master" or "release-2.3" etc + case (None, None) => "origin/master" // defaulting to diffing with "master" + } + }, + buildAllKeyword in Global in ValidatePR := """PLS BUILD ALL""".r, githubEnforcedBuildAll in Global in ValidatePR := { @@ -134,18 +149,34 @@ object ValidatePullRequest extends AutoPlugin { val prId = (sourceBranch in ValidatePR).value + val target = (targetBranch in ValidatePR).value + // TODO could use jgit log.info(s"Diffing [$prId] to determine changed modules in PR...") - val gitOutput = "git diff HEAD^ --name-only".!!.split("\n") - - val moduleNames = - gitOutput + val diffOutput = s"git diff $target --name-only".!!.split("\n") + val diffedModuleNames = + diffOutput .map(l ⇒ l.trim.takeWhile(_ != '/')) .filter(dir => dir.startsWith("akka-") || dir == "project") .toSet - log.info("Detected changes in directories: " + moduleNames.mkString("[", ", ", "]")) - moduleNames + val dirtyModuleNames: Set[String] = + if (runningOnJenkins) Set.empty + else { + val statusOutput = s"git status --short".!!.split("\n") + val dirtyDirectories = statusOutput + .map(l ⇒ l.trim.dropWhile(_ != ' ').drop(1)) + .map(_.takeWhile(_ != '/')) + .filter(dir => dir.startsWith("akka-") || dir == "project") + .toSet + log.info("Detected uncomitted changes in directories (including in dependency analysis): " + dirtyDirectories.mkString("[", ",", "]")) + dirtyDirectories + } + + + val allModuleNames = dirtyModuleNames ++ diffedModuleNames + log.info("Detected changes in directories: " + allModuleNames.mkString("[", ", ", "]")) + allModuleNames } )