diff --git a/README.md b/README.md index 7e9135b..dfbf7d8 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,24 @@ To specify encoding, add the following to your `build.sbt` scalacOptions += Seq("-encoding", "UTF-8") ``` +## Uploading coverage from multiple jobs in parallel + +Coveralls supports multiple CI jobs recording and uploading coverage, if a special flag is set and [a webhook](https://docs.coveralls.io/parallel-build-webhook) is posted once all jobs are complete. + +### Put the flag directly in your `build.sbt` + +``` scala +import org.scoverage.coveralls.Imports.CoverallsKeys._ + +coverallsParallel := true +``` + +### Add an environment variable + +Add an environment variable `COVERALLS_PARALLEL`, for example: + + export COVERALLS_PARALLEL=true + ## Using Travis-Pro It is important to set the correct `service_name` when using Travis-Pro. The default is to use `travis-ci`. To override this value, add the following to your `build.sbt` diff --git a/src/main/scala/org/scoverage/coveralls/CoverallPayloadWriter.scala b/src/main/scala/org/scoverage/coveralls/CoverallPayloadWriter.scala index 6c4c191..f42e9e0 100644 --- a/src/main/scala/org/scoverage/coveralls/CoverallPayloadWriter.scala +++ b/src/main/scala/org/scoverage/coveralls/CoverallPayloadWriter.scala @@ -12,6 +12,7 @@ class CoverallPayloadWriter( repoToken: Option[String], travisJobId: Option[String], serviceName: Option[String], + parallel: Boolean, gitClient: GitClient) { val repoRootDirStr = repoRootDir.getCanonicalPath.replace(File.separator, "/") + "/" @@ -35,6 +36,7 @@ class CoverallPayloadWriter( writeOpt("service_name", serviceName) writeOpt("service_job_id", travisJobId) writeOpt("service_pull_request", sys.env.get("CI_PULL_REQUEST")) + gen.writeBooleanField("parallel", parallel) addGitInfo diff --git a/src/main/scala/org/scoverage/coveralls/CoverallsPlugin.scala b/src/main/scala/org/scoverage/coveralls/CoverallsPlugin.scala index 97047a4..be7d6f3 100644 --- a/src/main/scala/org/scoverage/coveralls/CoverallsPlugin.scala +++ b/src/main/scala/org/scoverage/coveralls/CoverallsPlugin.scala @@ -22,6 +22,7 @@ object Imports { val coverallsEncoding = SettingKey[String]("encoding") val coverallsEndpoint = SettingKey[Option[String]]("coverallsEndpoint") val coverallsGitRepoLocation = SettingKey[Option[String]]("coveralls-git-repo") + val coverallsParallel = SettingKey[Boolean]("coverallsParallel") } } @@ -46,7 +47,8 @@ object CoverallsPlugin extends AutoPlugin { coverallsServiceName := travisJobIdent map { _ => "travis-ci" }, coverallsFile := crossTarget.value / "coveralls.json", coberturaFile := crossTarget.value / "coverage-report" / "cobertura.xml", - coverallsGitRepoLocation := Some(".") + coverallsGitRepoLocation := Some("."), + coverallsParallel := sys.env.get("COVERALLS_PARALLEL") == Some("true") ) val aggregateFilter = ScopeFilter(inAggregates(ThisProject), inConfigurations(Compile)) // must be outside of the 'coverageAggregate' task (see: https://github.com/sbt/sbt/issues/1095 or https://github.com/sbt/sbt/issues/780) @@ -83,6 +85,7 @@ object CoverallsPlugin extends AutoPlugin { repoToken, travisJobIdent, coverallsServiceName.value, + coverallsParallel.value, new GitClient(repoRootDirectory)(log) ) diff --git a/src/test/scala/com/github/theon/coveralls/CoverallPayloadWriterTest.scala b/src/test/scala/com/github/theon/coveralls/CoverallPayloadWriterTest.scala index 3a4bd15..9f385e7 100644 --- a/src/test/scala/com/github/theon/coveralls/CoverallPayloadWriterTest.scala +++ b/src/test/scala/com/github/theon/coveralls/CoverallPayloadWriterTest.scala @@ -21,8 +21,8 @@ class CoverallPayloadWriterTest extends WordSpec with BeforeAndAfterAll with Mat } } - def coverallsWriter(writer: Writer, tokenIn: Option[String], travisJobIdIn: Option[String], serviceName: Option[String]) = - new CoverallPayloadWriter(new File("").getAbsoluteFile, new File(""), tokenIn, travisJobIdIn, serviceName, testGitClient) { + def coverallsWriter(writer: Writer, tokenIn: Option[String], travisJobIdIn: Option[String], serviceName: Option[String], parallel: Boolean) = + new CoverallPayloadWriter(new File("").getAbsoluteFile, new File(""), tokenIn, travisJobIdIn, serviceName, parallel, testGitClient) { override def generator(file: File) = { val factory = new JsonFactory() factory.createGenerator(writer) @@ -36,13 +36,13 @@ class CoverallPayloadWriterTest extends WordSpec with BeforeAndAfterAll with Mat "generate a correct starting payload with travis job id" in { val w = new StringWriter() - val coverallsW = coverallsWriter(w, Some("testRepoToken"), Some("testTravisJob"), Some("travis-ci")) + val coverallsW = coverallsWriter(w, Some("testRepoToken"), Some("testTravisJob"), Some("travis-ci"), false) coverallsW.start coverallsW.flush() w.toString should equal( - """{"repo_token":"testRepoToken","service_name":"travis-ci","service_job_id":"testTravisJob",""" + + """{"repo_token":"testRepoToken","service_name":"travis-ci","service_job_id":"testTravisJob","parallel":false,""" + expectedGit + ""","source_files":[""" ) @@ -50,13 +50,13 @@ class CoverallPayloadWriterTest extends WordSpec with BeforeAndAfterAll with Mat "generate a correct starting payload without travis job id" in { val w = new StringWriter() - val coverallsW = coverallsWriter(w, Some("testRepoToken"), None, None) + val coverallsW = coverallsWriter(w, Some("testRepoToken"), None, None, false) coverallsW.start coverallsW.flush() w.toString should equal( - """{"repo_token":"testRepoToken",""" + + """{"repo_token":"testRepoToken","parallel":false,""" + expectedGit + ""","source_files":[""" ) @@ -64,7 +64,7 @@ class CoverallPayloadWriterTest extends WordSpec with BeforeAndAfterAll with Mat "add source files correctly" in { val w = new StringWriter() - val coverallsW = coverallsWriter(w, Some("testRepoToken"), None, Some("travis-ci")) + val coverallsW = coverallsWriter(w, Some("testRepoToken"), None, Some("travis-ci"), false) val projectRoot = new File("").getAbsolutePath.replace(File.separator, "/") + "/" @@ -80,13 +80,27 @@ class CoverallPayloadWriterTest extends WordSpec with BeforeAndAfterAll with Mat "end the file correctly" in { val w = new StringWriter() - val coverallsW = coverallsWriter(w, Some("testRepoToken"), None, Some("travis-ci")) + val coverallsW = coverallsWriter(w, Some("testRepoToken"), None, Some("travis-ci"), false) coverallsW.start coverallsW.end() w.toString should endWith("]}") } + + "include parallel correctly" in { + val w = new StringWriter() + val coverallsW = coverallsWriter(w, Some("testRepoToken"), None, None, true) + + coverallsW.start + coverallsW.flush() + + w.toString should equal( + """{"repo_token":"testRepoToken","parallel":true,""" + + expectedGit + + ""","source_files":[""" + ) + } } } }