Developer Zone

Advanced Software Development with MATLAB

Git to the Lab! 8

Posted by Andy Campbell,

Hello everyone, for this post, I'd like to introduce Mariano Lizarraga Fernandez as a guest blogger. He has a great story to share where he demonstrates a nicely tuned workflow between a Jenkins server and and a GitLab repository. Take it away Mariano!

The Big Picture

In this post we will present a workflow to show how we can run a MATLAB or Simulink Test suite on a Continuous Integration server every time we push to a git repository branch.

We will not describe in detail what Continuous Integration is and everything it involves. For those interested, we recommend this post as an introduction to the topic. This post introduces the concept of interfacing MATLAB with Jenkins, a well-known continuous integration server. Feel free to explore this and other CI related posts by looking at the Continuous Integration category.

In the following we assume that you have some basic familiarity with git and have a Jenkins server running (even locally) that has access to the git repository under test. We will be showing interactions between Jenkins and GitLab (a well-known open source git repository manager) and therefore you will need to install the GitLab plugin in Jenkins.

Let's go through the Workflow step by step.

For purposes of this post, we will assume a simplified continuous integration workflow as follows:

  1. Changes are made to code or a model, staged, and committed to a git repository's testing branch.
  2. Changes are pushed to a git remote's testing branch.
  3. The remote repository notifies (via a web hook) the Jenkins CI server that there has been a new push event.
  4. The Jenkins server pulls the changes from the git repository and runs a test suite.
  5. If a test fails, it creates a bug issue in GitLab, if the test passes, it creates a merge request.

Here is a picture illustrating this workflow:

Getting Jenkins Ready

We have written before in this blog how to go about setting up Jenkins to launch MATLAB unit tests. So here we'll focus on configuring it, so every time you push to the testing branch, a Jenkins workflow is triggered.

Start by creating a Freestyle project in Jenkins and configure your Source Code management tab to use git. Type the full address of your remote git repository, configure your credentials and make sure you set it to build from your testing branch.

Next, configure your project to build when a change is pushed to GitLab. Take note of the GitLab CI Service URL, as you will need it later to configure GitLab.

Finally, configure launching MATLAB with no display, changing directory to the Project's workspace, and running a script that we'll be writing in the following sections:

After that, save your changes. Your freestyle project is ready. Now off to GitLab.

Getting GitLab ready

In GitLab the first thing to do is to configure the Web Hook that will notify Jenkins when a push occurs. To do that, navigate to your settings and in the Integrations subsection, add the URL you wrote from the previous section, check the push events checkbox and click the Add Webhook button:

At this point you can test that your web hook triggers a build in Jenkins. To do that, in the same Integrations subsection in GitLab, select your webhook from the list, and using the Test button, select Push Events. You should immediately get a blue ribbon at the top indicating that your web hook executed successfully

Finally, since we will be using GitLab's RESTful API to create issues and merge requests, you'll need to get a Personal Access Token. To do that, go to your personal settings, (in the rightmost corner on a standard GitLab instance) and from there go to your Access Tokens subsection. This will take you to the Access Token creation page. Select a Name, choose an expiration date (you can also leave it blank) and for the scope check the API checkbox.

After you click the green Create personal access token button, you will be taken to a page that shows you the token. Make sure you record that token somewhere as you will not be able to see it again. We will use that token when we write our MATLAB script to run the tests in Jenkins.

Testing Script

We will use a variation of the script published for this Simulink's Blog post.

Convert it to a function to receive one argument: The argument will determine if it ran in continuous Integration or locally. This will allow us to test things locally then push it to server to run there.

function runMyTests (ranInCI)

import matlab.unittest.TestRunner
import matlab.unittest.plugins.TAPPlugin
import matlab.unittest.plugins.ToFile

workspace = pwd;

if ranInCI == 1
    resultsLocation = fullfile(pwd, 'results');


Collect Data about the current commit: So we can put comments on the issues or merge request about which commit passed and needs to be merged (or failed and needs to be fixed).

% Collect data from the current commit to include in the
% body of the issue or merge request.
[~, commit] = system('git rev-parse --short HEAD');
[~, branch] = system('git rev-parse --abbrev-ref HEAD');

Do a web GET or POST to GitLab's API: We will use webwrite and webread to create the issues and merge requests as necessary. Note that in you will need the private token created in GitLab.

if ranInCI == 1
    copyfile(tapResultsFile, fullfile(resultsLocation, 'TAPResults.tap'));
    totalFailures = sum(vertcat(results(:).Failed));
    writeOptions = weboptions('MediaType','application/x-www-form-urlencoded',...
                              'HeaderFields', ...
                              {'PRIVATE-TOKEN', gitPrivateToken});
    if totalFailures == 0
        % If no failures, create a merge request
        writeMergeURL = [gitLabAPI 'projects/' ProjectID '/merge_requests?'];
        webwrite(writeMergeURL, ...
                 'title', ...
                 ['[Jenkins] Test(s) Passed for commit ' strtrim(commit)], ...
                 'description', ...
                 ['Continous Integration passed on commit ' strtrim(commit) ...
                     ' of branch ' strtrim(branch) ...
                     '. Merge request ready for review'], ...
                 'labels', 'merge_request', ...
                 'source_branch', strtrim(branch), ...
                 'target_branch', 'master', ...
                 'approvals_before_merge', '3', ...
        % Tests failed, create a test failure issue in GitLab
        writeIssueURL = [gitLabAPI 'projects/' ProjectID '/issues?'];
        webwrite(writeIssueURL, ...
                 'title', ...
                 ['[Jenkins] Test(s) Failing in commit ' strtrim(commit)], ...
                 'description', ...
                 ['Continous Integration Failed when running on commit ' ...
                 strtrim(commit) ' of branch ' strtrim(branch) '.'], ...
                 'labels', 'bug', ...

Putting it all Together

Now you are ready to test the complete workflow. You can take a look at the video below showing the complete process. Note, the video is a silent film, no need to crank up your audio.

If you are working on MATLAB and using git for source control, consider making use of a continuous integration server to automate your testing and making sure that your tests are run. Give it a try and let us know what you think!

8 CommentsOldest to Newest

Steve replied on : 1 of 8
Hi thanks. Are you running MATLAB, gitlab and Jenkins on: 1. all on a local dev machine 2. all in the cloud 3. some mix of the 2?
Federico Felici replied on : 2 of 8
Hello, does anyone have experience in running MATLAB tests directly from GitLab's CI environment? Or can point me to examples?
@Steve, sorry for the delayed response! For this post we were running MATLAB on a local machine

@Federico, we don't have an example of this but certainly we have done it. Perhaps this is a good future post?
Pierre Meslot replied on : 4 of 8
@Frederico, I did some test at home with Gitlab CI and Matlab, it is fairly straightforward to set up. The problem I am running into at the minute is that my Matlab license (Matlab home) is bound to my user name and the runner seem to have its own user name (it sits in /home/gitlab-runner) Therefore the runner fails to launch Matlab... When I run the bash script the runner executes manually from my user account, everything works just fine. @Andy, is there a way to get around that or is a runner is viewed as a user and therefore needs it own license?
Pierre Meslot replied on : 5 of 8
@Frederico, I did do some tests setting up a CI envirionmenent for MATLAB using the gitlab runners. The runner was intalled on my linux machine (The machine I use matlab for dev) but my home license is tied up to my user account and the runner seem to be a separate user (it sits in /home/gitlab-runner, not under /home/). Therefore it failed to open matlab. Not how to get around that, and whether that would be any different with a mix gitlab/jenkins setup... Need to try that.
Federico Felici replied on : 7 of 8
Thanks, I got this working now following roughly this link: In my case, I used a gitlab-runner SSH executor to run commands on a machine that has matlab (with license) installed.
Akshat Sharma replied on : 8 of 8
Hello, Thanks for the great post I am trying to imitate this workflow on Windows. I wrote a batch file that can start Matlab and change to the cloned git repo. This batch file works when I call it from the command prompt however when I try the same from a Jenkins job, the job builds succesfully however Matlab does not come up. To verify my job is set up correctly, I wrote a different batch file that starts chrome and that works perfectly. What do you think I might be doing wronmg here ? Thanks Akshat Sharma