> ## Documentation Index
> Fetch the complete documentation index at: https://docs.semgrep.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Run Semgrep in Jenkins when using Bitbucket as the source code manager

To scan your code hosted by Bitbucket with Semgrep using a Jenkins project or pipeline, you must:

1. Set up webhooks to connect Jenkins to Bitbucket.
2. Configure the Jenkins project or pipeline to run Semgrep.

## Set up webhooks to allow triggering events from Bitbucket to Jenkins

Webhooks are required to connect your Bitbucket source code manager (SCM) to Jenkins.

<Note>
  **PREREQUISITES**

  You must install the <Icon icon="external-link" iconType="solid" /> Bitbucket Push and Pull Request plugin on your Jenkins server. This method requires that your Jenkins instance be compatible with this plugin.
</Note>

<Steps>
  <Step>
    Log in to Bitbucket, and go to your repository.
  </Step>

  <Step>
    In your Bitbucket repository, go to **Repository Settings > Webhooks > Add webhook**.
  </Step>

  <Step>
    Enter a **Title** for your webhook.
  </Step>

  <Step>
    Enter the **URL** for your Jenkins instance using the following pattern: `https://<YOUR_JENKINS_SERVER>/bitbucket-hook/`.
  </Step>

  <Step>
    Add the following **Triggers**:<br />
      i. In the **Repository** list, select **Push**.<br />
      ii. In the **Pull request** list, select **Created** and **Updated**.
  </Step>
</Steps>

## Configure Jenkins to run Semgrep

<Tabs>
  <Tab title="Pipeline">
    <Steps>
      <Step>
        Sign in to Jenkins.
      </Step>

      <Step>
        From the **Jenkins Dashboard** click on create a **New Item**.
      </Step>

      <Step>
        Enter a project name, select **Pipeline** option, and click **OK**.
      </Step>

      <Step>
        In the **General > Triggers** section, select **Build with BitBucket Push and Pull Request Plugin**.
      </Step>

      <Step>
        Create the **Triggers**:<br />
          i. Click **Add**.<br />
          ii. Select one of the following: **Bitbucket Cloud Pull Request**, **Bitbucket Server Pull Request**, or **Push**.<br />
          iii. In **Select an Action**, select **Created**.<br />
          iv. Click **Add** again, and select the same trigger as before: **Bitbucket Cloud Pull Request**, **Bitbucket Server Pull Request**, or **Push**.<br />
          v. In **Select an Action**, select **Updated**.
      </Step>

      <Step>
        Go to the **Pipeline** section. In **Definition**, select **Pipeline script from SCM**.<br />
          i. In **SCM**, select **Git**.<br />
          ii. In **Repositories > Repository URL**, enter your Bitbucket repository URL.<br />
          iii. In **Branch Specifier (blank for 'any')**, enter the name of your main branch.<br />
          iv. In **Script Path**, enter `Jenkinsfile`.
      </Step>

      <Step>
        Click **Save**.
      </Step>
    </Steps>

    ### Create and add the Jenkinsfile to your repository

    Create the Jenkinsfile in your Bitbucket repository. The file must define the logic to start:

    * Diff-aware scans if the scan is started in the context of a pull request
    * Full scans if you push changes to the main branch

    The following code snippets are sample Jenkinsfiles that define both of these actions. Choose the file for your deployment based on whether you're using Bitbucket Cloud or Bitbucket Data Center.

    <Tabs>
      <Tab title="Bitbucket Cloud">
        ```groovy expandable theme={null}
        pipeline {
          agent any
          environment {
            SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
            SEMGREP_BASELINE_REF = "origin/main"
          }
          stages {
            stage('Semgrep-Scan') {
              steps {
                script {
                  if (env.BITBUCKET_PULL_REQUEST_ID) {
                    echo "Semgrep diff scan"
                    sh '''git checkout ${BITBUCKET_PULL_REQUEST_LATEST_COMMIT_FROM_SOURCE_BRANCH}'''
                    sh '''git fetch origin +ref/heads/*:refs/remotes/origin/*'''
                    sh '''docker run \
                      -e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
                      -e SEMGREP_PR_ID=${BITBUCKET_PULL_REQUEST_ID} \
                      -e SEMGREP_BASELINE_REF=$SEMGREP_BASELINE_REF \
                      -v "$(pwd):$(pwd)" --workdir $(pwd) \
                      semgrep/semgrep semgrep ci'''
                  } else {
                    echo "Semgrep full scan"
                    sh '''docker run \
                      -e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
                      -v "$(pwd):$(pwd)" --workdir $(pwd) \
                      semgrep/semgrep semgrep ci'''
                  }
                }
              }
            }
          }
        }
        ```

        Note that:

        * You must define `SEMGREP_APP_TOKEN` in Jenkins. You can [create the required token in Semgrep AppSec Platform](https://semgrep.dev/orgs/-/settings/tokens/cli).
        * The variable `SEMGREP_BASELINE_REF` in the code snippet must be set to the primary or default branch, which in the example is `origin/main`.
      </Tab>

      <Tab title="Bitbucket Data Center">
        ```javascript expandable theme={null}
        pipeline {
          agent any
            environment {
              // The following variable is required for a Semgrep AppSec Platform-connected scan:
              SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
              BITBUCKET_TOKEN = credentials('FS_BITBUCKET_TOKEN')

              // Uncomment the following line to scan changed
              // files in PRs or MRs (diff-aware scanning):
              // SEMGREP_BASELINE_REF = "${env.CHANGE_ID != null ? 'main' : ''}"

              // Troubleshooting:

              // Uncomment the following lines if Semgrep AppSec Platform > Findings Page does not create links
              // to the code that generated a finding or if you are not receiving PR or MR comments.
              // SEMGREP_JOB_URL = "${BUILD_URL}"
              // SEMGREP_COMMIT = "${GIT_COMMIT}"
              // SEMGREP_BRANCH = "${GIT_BRANCH}"
              // SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/YOUR_BITBUCKET_DATA_CENTER_URL\/scm\/(.*).git$/, '$1')
              // SEMGREP_REPO_URL = env.GIT_URL.replaceFirst(/^(https:\/\/.*?)\/scm\/(.*)\/(.*)\.git$/, '$1/projects/$2/repos/$3')
              // SEMGREP_PR_ID = "${env.CHANGE_ID != null ? env.CHANGE_ID : ''}"
              SEMGREP_APP_URL = "https://semgrep.dev"
            }
            stages {
              stage('Semgrep-Scan') {
                steps {
                    sh 'pipx install semgrep'
                    sh 'semgrep ci'
                }
            }
          }
        }
        ```
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Freestyle">
    To set up a Freestyle project to scan your Bitbucket projects with Semgrep:

    <Steps>
      <Step>
        Sign in to Jenkins.
      </Step>

      <Step>
        [Define `SEMGREP_APP_TOKEN` as a credential](https://www.jenkins.io/doc/book/using/using-credentials/#configuring-credentials) in Jenkins. You will add this credential to your project at a later step.
      </Step>

      <Step>
        From the Jenkins **Dashboard**, click **New Item**.
      </Step>

      <Step>
        Type a project name, select **Freestyle project**, and click **OK**.
      </Step>

      <Step>
        Go to **General > Source Code Management**. Select **Git**. Then:<br />
          i. Add your Bitbucket **Repository URL**<br />
          ii. Add the **Credentials** needed to check out your sources<br />
          iii. Add the **Branches to build**
      </Step>

      <Step>
        In the **Triggers** section, select **Build with Bitbucket Push and Pull Request Plugin**. Then, create the **Triggers**:<br />
          i. Click **Add**.<br />
          ii. Select one of the following: **Bitbucket Cloud Pull Request** or **Bitbucket Server Pull Request**.<br />
          iii. In **Select an Action**, select **Created**.<br />
          iv. Click **Add** again, and select the same trigger as before: **Bitbucket Cloud Pull Request** or **Bitbucket Server Pull Request**.<br />
          v. In **Select an Action**, select **Updated**.<br />
          vi. Click **Add > Push**.<br />
      </Step>

      <Step>
        Next, add your Semgrep token to the environment:<br />
          i. In the **Environment** section, select **Use secret text(s) or file(s)**.<br />
          ii. Under **Bindings**, select **Secret text**.<br />
          iii. Set **Variable** to `SEMGREP_APP_TOKEN`.<br />
          iv. Under **Credentials > Specific credentials**, choose the defined credential for the token.<br />
          v. Click **Add** to save your changes.
      </Step>

      <Step>
        In the **Build Steps** section, click **Add build step > Execute shell**. In **Command**, provide one of the following scripts to run Semgrep:

        ```bash expandable theme={null}
        #!/bin/bash
        BASELINE_REF="main"
        BASELINE_REF_ORIGIN="origin/$BASELINE_REF"
        REPO_URL=$GIT_URL
        REPO_NAME=$(echo "$GIT_URL" | awk -F'/' '{print $(NF-1)"/"$(NF)}' | sed 's/.git$//')

        ## Merge or push to primary branch
        if [ $BITBUCKET_SOURCE_BRANCH = $BASELINE_REF ]; then
            docker run -e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
                      -e SEMGREP_REPO_URL=$REPO_URL \
                      -e SEMGREP_REPO_NAME=$REPO_NAME \
                      -v "$(pwd):$(pwd)" --workdir $(pwd) \
                      semgrep/semgrep semgrep ci
        ## pull request scans
        elif [ $BITBUCKET_PULL_REQUEST_ID -ge 0 ]; then
            git checkout $BITBUCKET_SOURCE_BRANCH && git pull
            docker run -e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
                  -e SEMGREP_BASELINE_REF=$BASELINE_REF_ORIGIN \
                  -e SEMGREP_REPO_URL=$REPO_URL \
                  -e SEMGREP_REPO_NAME=$REPO_NAME \
                  -e SEMGREP_BRANCH=$BITBUCKET_SOURCE_BRANCH \
                  -e SEMGREP_PR_ID=$BITBUCKET_PULL_REQUEST_ID \
                  -v "$(pwd):/src" \
                  semgrep/semgrep semgrep ci
        fi
        ```

        <Info>
          **NOTE**

          * The variable `SEMGREP_BASELINE_REF` must be set to the default branch, which is `main` in the preceding example.
          * The configuration for a diff-aware scan must specify a merge base against which the pull request changes are compared. To do this:
            * Set the pull request target branch as `SEMGREP_BASELINE_REF`
            * Set `SEMGREP_BRANCH` to the pull request source branch to ensure it's correctly identified.
            * Set `SEMGREP_PR_ID` so that Semgrep can send comments to the relevant pull request.
        </Info>
      </Step>
    </Steps>
  </Tab>
</Tabs>

### Test the implementation

To ensure that Semgrep scans correctly in your Jenkins pipeline or project:

1. Commit a change to your repository, and create a pull request. This automatically runs a Semgrep diff-aware scan in Jenkins. Note that the job can fail if there are blocking findings as a result of the scan.
2. Merge the pull request to commit the changes to `main`. This triggers a full scan in Jenkins.
