Skip to main content

Integrate preZero into the GitLab Merge Request Workflow

This article shows you how to integrate Qwiet preZero into your GitLab Merge Request Workflow for automated code analysis whenever you create a new PR.

Background

Integrating preZero into your GitLab Merge Request workflow is done using the pipelines for merge requests that GitLab includes in its premium version.

We assume that you're working with a GitLab repo that utilizes GitLab's built-in CI pipelines and Linux-based runners, though you could use GitLab's [runners] as an alternative.

Prerequisites

To facilitate communication between Qwiet and GitLab, please create the required environment variables and API access token as described in the following two sections.

Set the environment variable

Create a custom environment variable so that GitLab can communicate and use Qwiet. Name this variable SHIFTLEFT_ACCESS_TOKEN, and set it to the value found in the Dashboard under Access Token.

However, when running in a production environment, we recommend using a CI token as the access token. You can create your CI token in the Qwiet Dashboard.

Please note that the presence of any set environment variables will override those in a configuration file.

GitLab API access

Configure a personal access token to authenticate Qwiet with the GitLab API. Name it MR_TOKEN for use in the bash script used to run preZero, and make sure to assign it the api and read_api scopes.

Step 1: Mandate successful merge checks

As a GitLab administrator, you can edit your project properties to enforce branch protection rules. Go to Settings > General and expand the Merge Requests section. Scroll down to Merge checks and make sure that both are checked:

  • Pipelines must succeed
  • All discussions must be resolved

GitLab merge check settings

Step 2: Configure the GitLab Pipelines configuration file and include code analysis

The .gitlab-ci.yml file controls the jobs executed in GitLab pipelines, and this is where you can insert instructions to run the preZero code review process.

If you don't already have a .gitlab-ci.yml file in your project repository, you must create one.

Once you've created the configuration file, you can add the following snippet to the rest of your YAML file to invoke code analysis for merge_request events:

Analyze code with preZero:
stage: test
dependencies:
- build
image:
name: ubuntu:latest
script:
# Ensure curl and jq are installed
- apt update && apt install -y curl jq
# Install sl
- curl https://cdn.shiftleft.io/download/sl >/usr/local/bin/sl && chmod a+rx /usr/local/bin/sl
# Run preZero script
- sh sl-analysis.sh
rules:
- when: always

Here is what a complete .gitlab-ci.yml file could look like for a Maven project:

image: maven:latest
Build code:
stage: build
artifacts:
paths:
- target/
script:
- mvn package
rules:
- when: always
Analyze code with preZero:
stage: test
dependencies:
- Build code
image:
name: ubuntu:latest
script:
# Ensure curl and jq are installed
- apt update && apt install -y curl jq
# Install sl
- curl https://cdn.shiftleft.io/download/sl >/usr/local/bin/sl && chmod a+rx /usr/local/bin/sl
# Run preZero script
- sh sl-analysis.sh
rules:
- when: always

Note that the configuration file calls a script called sl-analysis.sh. You will need to add the file, which includes the code shown below, to the root of your repository (be sure to modify the placeholder variables as indicated in the file's comments):

#!/bin/sh

#### Analyze code

SHIFTLEFT_SBOM_GENERATOR=2 sl analyze \
--app "$CI_PROJECT_NAME" \
--tag branch="$CI_COMMIT_REF_NAME" \
--wait \
target/war-or-jar-file-name # Change this

#### Run build rules

# Check if this is running in a merge request
if [ -n "$CI_MERGE_REQUEST_IID" ]; then
echo "Got merge request $CI_MERGE_REQUEST_IID for branch $CI_COMMIT_REF_NAME"

# Run check-analysis and save report to /tmp/check-analysis.md
sl check-analysis \
--app "$CI_PROJECT_NAME" \
--report \
--report-file /tmp/check-analysis.md \
--source "tag.branch=master" \
--target "tag.branch=$CI_COMMIT_REF_NAME"

CHECK_ANALYSIS_OUTPUT=$(cat /tmp/check-analysis.md)
COMMENT_BODY=$(jq -n --arg body "$CHECK_ANALYSIS_OUTPUT" '{body: $body}')

# Post report as merge request comment
curl -i -XPOST "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" \
-H "PRIVATE-TOKEN: $MR_TOKEN" \
-H "Content-Type: application/json" \
-d "$COMMENT_BODY"
fi

Please note that the script above includes a section that runs build rules; we will cover build rules in the following sections.

Step 3: Configure your build rules

preZero allows you to create build rules, which define the security approval conditions that must be met before merging a merge request. You can define build rules in the shiftleft.yml configuration file in the root of your repository. For additional information, please see How to work with build rules v2 in your repo.

Step 4: Push your files to GitLab

Once you've created the following files, commit them to your project and push them to GitLab:

  • .gitlab-ci.yml
  • shiftleft.yml
  • sl-analysis.sh

Please note that GitLab will automatically create a pipeline for you once you push .gitlab-ci.yml.

Step 5: Testing the workflow

At this point, you can test your workflow. When you begin merging your changes into your master branch, Qwiet will run, analyze your code, and indicate whether the merger should fail or not based on the build rules you define.

For example, if one of your build rules is violated, you will see the following result in your build logs:

GitLab build logs

GitLab will also report that a build rule failed:

GitLab Conversation