> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/sast-and-sca/prezero/static-analysis-sast/workflows/gitlab.md).

# Gitlab

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

## Background <a href="#background" id="background"></a>

Integrating Qwiet AI by Harness into your GitLab Merge Request workflow is done using the [pipelines](https://about.gitlab.com/pricing/gitlab-com/feature-comparison/) for merge requests that GitLab includes in its [premium version](https://about.gitlab.com/pricing/gitlab-com/feature-comparison/).

We assume that you're working with a GitLab repo that utilizes GitLab's built-in CI [pipelines](https://gitlab.com/help/ci/merge_request_pipelines/index.md#pipelines-for-merge-requests) and [Linux-based runners](https://docs.gitlab.com/runner/), though you could use GitLab's \[runners] as an alternative.

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

To facilitate communication between Qwiet and GitLab, please create the required [environment variables](#set-the-environment-variable) and [API access token](#gitlab-api-access) as described in the following two sections.

### Set the environment variable <a href="#set-the-environment-variable" id="set-the-environment-variable"></a>

Create a [custom environment variable](https://docs.gitlab.com/ee/ci/variables/#custom-environment-variables) so that GitLab can communicate and use Qwiet. Name this variable `SHIFTLEFT_ACCESS_TOKEN`, and set it to the value found in the [Dashboard](https://app.shiftleft.io/user/profile) 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](/sast-and-sca/prezero/integrations/tokens.md) in the Qwiet Dashboard.

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

### GitLab API access <a href="#gitlab-api-access" id="gitlab-api-access"></a>

Configure a [personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) to authenticate Qwiet with the GitLab API. Name it `MR_TOKEN` for use in the bash script used to run Qwiet AI by Harness, and make sure to assign it the `api` and `read_api` scopes.

## Step 1: Mandate successful merge checks <a href="#step-1-mandate-successful-merge-checks" id="step-1-mandate-successful-merge-checks"></a>

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](/files/HP5qb5EXWodzRmZEWTWq)

## Step 2: Configure the GitLab Pipelines configuration file and include code analysis <a href="#step-2-configure-the-gitlab-pipelines-configuration-file-and-include-code-analysis" id="step-2-configure-the-gitlab-pipelines-configuration-file-and-include-code-analysis"></a>

The [.gitlab-ci.yml file](https://gitlab.com/help/ci/yaml/README.md) controls the jobs executed in GitLab pipelines, and this is where you can insert instructions to run the Qwiet AI by Harness 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 Qwiet AI by Harness:
  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 Qwiet AI by Harness script
    - sh sl-analysis.sh
  rules:
    - when: always
```

![](/files/CRrxFX9wuboXxDrdB2dv)

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

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 Qwiet AI by Harness:
  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 Qwiet AI by Harness script
    - sh sl-analysis.sh
  rules:
    - when: always
```

![](/files/CRrxFX9wuboXxDrdB2dv)

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

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
```

![](/files/CRrxFX9wuboXxDrdB2dv)

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

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 <a href="#step-3-configure-your-build-rules" id="step-3-configure-your-build-rules"></a>

Qwiet AI by Harness allows you to create [build rules](/sast-and-sca/prezero/customization/build-rules-v2.md), 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](/sast-and-sca/prezero/customization/build-rules-v2.md).

## Step 4: Push your files to GitLab <a href="#step-4-push-your-files-to-gitlab" id="step-4-push-your-files-to-gitlab"></a>

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](https://docs.gitlab.com/ee/ci/quick_start/#push-gitlab-ciyml-to-gitlab) for you once you push .gitlab-ci.yml.

## Step 5: Testing the workflow <a href="#step-5-testing-the-workflow" id="step-5-testing-the-workflow"></a>

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](/files/phbVbsX8JF5SJwDKi6cU)

GitLab will also report that a build rule failed:

![GitLab Conversation](/files/qliTkvzOActCKDZsyTX1)
