Tales from a n00b: CI for Flutter using Jenkins and Docker: Episode 2
In Episode 1 of this series, I told you guys why I chose Jenkins and how I created a docker image with Jenkins and Flutter installed. Right before I went to read more documentation, I had a Jenkins instance running on the localhost and assuming that you guys followed through you at least have had a Jenkins instance running. Now, let us continue and configure Jenkins to start a flutter test build whenever we push a commit to our git repo.
Setting up Credentials
We will start by adding our Github credentials to Jenkins. To do this click on the Credentials
options available on the Jenkins home page and then select the global scope. On the next screen click on Add Credentials
. Select Username with password
from the drop-down, you are free to use any other option if you want, but I found that while setting multibranch pipeline it was not working with my Secret text credentials.
Install Cobertura plugin
In order to collect code coverage, we will need to install a plugin on Jenkins. After looking around I found that the Cobertura plugin seems to be well integrated with Jenkins, so we are going to install it. To install this plugin go to Manage Jenkins
-> Manage Plugins
. On the Available tab search for Cobertura and install the plugin. It will also be a good time to restart your Jenkins server.
Create a Jenkinsfile
To instruct Jenkins how to perform your build we need to create a Jenkinsfile. Jenkinsfile is a text file which contains the definitions of a Jenkins Pipeline and we will be using a pipeline for running flutter test
. My Jenkinsfile looks like this and I will walk through each step.
stage ('Checkout') {
steps {
checkout scm
}
}
We start our pipeline by checking out the code from git.
stage ('Download lcov converter') {
steps {
sh "curl -O https://raw.githubusercontent.com/eriwen/lcov-to-cobertura-xml/master/lcov_cobertura/lcov_cobertura.py"
}
}
Remember the Cobertura plugin from earlier, as it happens Cobertura has it’s own syntax for code coverage report and uses a XML file. But our flutter test — coverage
generates the report in LCOV format, which is a problem for us. To get over this problem I am using a script that converts lcov reports to cobertura, this is available on Github. In this step of our pipeline, we are just downloading this script from Github and saving it.
The next step is simply running flutter doctor
to check the health of our flutter installation.
stage('Test') {
steps {
sh "flutter test --coverage"
}
post {
always {
sh "python3 lcov_cobertura.py coverage/lcov.info --output coverage/coverage.xml"
step([$class: 'CoberturaPublisher', coberturaReportFile: 'coverage/coverage.xml'])
}
}
}
This is the step where all the fun happens, this is where we run flutter test
. I have configured this step to run flutter test with coverage all the time but we can always perform some additional optimizations. I have added a post-completion step where the script from before is run to convert our lcov report to cobertura report, once that is done I am instructing Cobertura plugin to pick up the coverage report.
stage('Run Analyzer') {
steps {
sh "dartanalyzer --options analysis_options.yaml ."
}
}
For the final step, I am running dartanalyzer
on the project using the analysis_options.yaml
saved in my project.
All that is required now is to add this Jenkinsfile to our Flutter project root.
Create a Multibranch Pipeline
Select New Item
on the Jenkins home page. On the next screen enter a name for your project, select Multibranch Pipeline
option and click OK.
On the next screen provide a Display Name and Description for the project and scroll down to Branch Sources option. Click on Add source and select Github if you are using github.com or Git if you have any other git (I will use Git because I have my project on Github enterprise). Provide the owner of the repository and select the repository. Leave the Behaviors as default.
In the Build Configuration section leave it as by Jenkinsfile
and Script Path
as Jenkinsfile. This basically tells Jenkins that the definitions of the pipeline will be contained in a Jenkinsfile that we created before and it will be available in the repo.
In Scan Multibranch Pipeline Triggers option check Periodically if not otherwise run
and select an Interval that works best for you. In my case, I am selecting 5 minutes.
Leave the other options as default and click Save.
On clicking Save the project performs a Scan to look for Jenkinsfile in the repo and will start building the branches which contain the Jenkinsfile we created before, based on the configurations specified in the file.
You will be able to see the system starting a build on the branches that contain the Jenkins file. And now next time whenever you push your code to any of the branches that contain the Jenkinsfile, it will start the build and you will be able to get your stats on the dashboard.
On clicking any of the branches you will be able to see the different builds on that branch as well as the coverage reports.
So that’s all folks! We have a build server running which is configured to start a test build every time we push a commit to our git repo. This is a basic setup but it is highly customizable and more steps could be added to get a Continuous Delivery system.
Hope this article was informative in some way and I really hope it helps someone. I am looking forward to feedback, as this is the first time I wrote something.
I am still trying to figure out how to post the dartanalyzer reports back to Jenkins, if someone knows how to do that please let me know.
References/Resources:
https://www.mirantis.com/blog/intro-to-cicd-how-to-make-jenkins-build-on-github-changes/
https://blog.doordash.com/integrating-github-with-jenkins-for-continuous-integration-and-deployment-7cae2c2161cb
https://medium.com/@elisegev/running-tests-and-creating-code-coverage-reports-for-react-nodejs-project-continuously-with-60312b6a2dd0
lcov-to-cobertura-xml: https://github.com/eriwen/lcov-to-cobertura-xml
Docker image with Jenkins and Flutter: https://hub.docker.com/r/ssiddh/jenkinsflutter/