+pro enable validatePullRequest locally

This commit is contained in:
Konrad Malawski 2016-01-22 00:56:25 +01:00
parent 55425e5ef3
commit dd1bf6a1ee
3 changed files with 63 additions and 6 deletions

View file

@ -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:

View file

@ -1,4 +1,5 @@
import akka.{ AkkaBuild, Formatting, OSGi, Unidoc, Dependencies }
import com.typesafe.tools.mima.plugin.MimaKeys
AkkaBuild.defaultSettings

View file

@ -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
}
)