Travis CI Scala Play Application Build & Deployment Optimization - scala

I have a project on GitHub where I'm using Travis CI for doing CI & CD. It is a Scala application built using sbt and runs as a web app using the Play framework. I have written the build pipeline such that I do the following as build stages:
jobs:
include:
- stage: test
script: sbt clean coverage test coverageReport
- stage: assemble-jar
script: sbt "set test in assembly := {}" assembly
if: branch = master
- stage: push-docker
script: bash docker_push.sh
if: branch = master
The problem that I face now is that during the test stage, it gets formatted and compiled once and so does it during the assembly and once again during the push-docker stage. This is quite annoying given the fact that how slow the Scala compiler is. Is there any way to optimize this such that it does not get compiled for every single stage? I did learn about caches and have the following as well in my yml:
cache:
directories:
- "$HOME/.ivy2/cache"
- "$HOME/.sbt"
But that unfortunately does not help as it caches only the dependencies but not the result of the previous build stage. What could I do to make it better?

First, you cannot really re-use the compiled class files of the test stage, since these have scoverage instrumentation embedded which makes them depend on scoverage at runtime. It will crash when you try to run without it.
Second, if you want to share build files between the assemble-jar and push-docker stages, you may use S3 to do so: https://docs.travis-ci.com/user/build-stages/share-files-s3/

Related

How to get code coverage in Sonarqube to work properly for scala?

I have a single-module Gradle build that compiles Scala code. I would like to scan the code, collect code coverage and feed the results into Sonarqube.
I am running the below command:
gradle --no-daemon -Dsonar.host.url=http://localhost:9000 -Dsonar.login=sqp_b*****7575 -Dsonar.sources=src/main/scala -Dsonar.scoverage.reportPath=central-intg-validation-core/build/reports/scoverage/scoverage.xml clean test reportScoverage sonarqube
which is resulting the output in the command line as below:
To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/7.4.2/userguide/gradle_daemon.html#sec:disabling_the_daemon.
Daemon will be stopped at the end of the build
> Task :central-intg-validation-core:reportTestScoverage
[info] Found 1 subproject scoverage data directories [central-intg-validation/central-intg-validation-core/build/scoverage]
> Task :central-intg-validation-core:reportScoverage
[info] Found 1 subproject scoverage data directories [/central-intg-validation/central-intg-validation-core/build/scoverage]
BUILD SUCCESSFUL in 25s
10 actionable tasks: 10 executed
When I open central-intg-validation/central-intg-validation-core/build/scoverage-aggregate/index.html, I can see:
here are clearly code coverage numbers in there.
So, when I run the sonar-scanner in order to send the information to Sonarqube, I don't see anything the sonarqube as below.
What am I doing wrong and why aren't there any code coverage numbers? Could somebody, please shed some light on this? I've been trying to get this right for a very long time. If it's a bug, or unfinished features, then finding this out would also be helpful.

In Azure DevOps, how do I prevent build from failing if unit tests fail

I have a build pipeline for simple .net project . There are some unit tests also which is failing . But I dont want the build job to fail and I want the artifacts to be published if unit tests are failing. How to achieve this.
I used ContinueOnError on the VStest Task. It dint publish artifacts and it doesnt show build job as passed.
Try adding failTaskOnFailedTest on your task
- task: PublishTestResults#2
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
failTaskOnFailedTests: false

How to chain SBT task with multi module project

I have configured one SBT multi-module project with scoverage plugin, which is working fine.
To generate test coverage, I am using > SBT clean coverage test coverageReport but is there any way to create a new task which chains internally coverage test coverageReport.
I have tried
Run custom task automatically before/after standard task to create a custom task, but it seems not working with multimodule project.
And one more - http://eed3si9n.com/sequencing-tasks-with-sbt-sequential
Try addCommandAlias like so
addCommandAlias("coverageAll", ";clean;coverage;test;coverageReport")
Now executing sbt coverageAll should generate coverage report for all the sub-projects.

GitHub and Travis CI - How to fail build when tests fail

I have a Scala project on GitHub and I use the Travis CI to build it and show the resulting badge on the project home in GitHub. I started to write unit tests and I realized that during one of my commit, some tests failed. But the travis build shows that the build passes.
I know that I should be using some kind of hook to check for tests failures and correspondingly fail my build. But I just don't know what the correct command for that is? I could not as well infer this from any documentation.
Here is my travis.yml file:
language: scala
jdk:
- oraclejdk8
scala:
- 2.11.7
script:
- sbt clean coverage test coverageReport
after_success:
- bash <(curl -s https://codecov.io/bash)
What hook should I add here so that the build fails as soon as one of my unit test fails?

sbt ignore test failures

For SonarQube jobs in Jenkins we'd like to proceed even though some tests might fail. Currently the Sonar Runner is not kicked off, because a test fails.
In Maven you'd just add -DtestFailureIgnore = true, but I cannot find anything similar for SBT.
I did find a onFailure thing for sbt, but have not found any examples anywhere how to use this. Could this be used to ignore test failures so the build job continues so the Sonar Runner gets started afterwards?
Or is there a setting in Jenkins to ignore the result of the build?
We use 'sbt clean coverage test coverageReport' as build command and have Sonar Runner in a post-build step.
Finally found a solution myself.
In SBT you can define a new task A which captures the result of another task B. This dependency ensures that task B is run when the new task A is started. By capturing the result, the result of task B is not the result of task A so if B fails, A does not (have to) fail.
So in this case, I added created a new 'ciTests' tasks to the 'build.sbt'
// Define a special test task which does not fail when any test fails,
// so sequential tasks (like SonarQube analysis) will be performed no matter the test result.
lazy val ciTests = taskKey[Unit]("Run tests for CI")
ciTests := {
// Capture the test result
val testResult = (test in Test).result.value
}
Now in the Jenkins job it build the project using SBT with commands (using SCoverage SBT plugin):
update coverage ciTests coverageReport
This build will succeed ignoring any failing tests. Therefore a next build step to start SonarRunner will start the analysis of the Scala project and put the results in SonarQube.
Thanks to #hugo-zwaal for pointing me to this answer which helped me solving my issue.