> 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/continuous-integration/3.0/use-harness-ci/use-harness-ci/codebase-configuration/scm-status-checks.md).

# SCM status checks

Configure branch protection and status checks for codebases associated with Harness CI.

If your pipelines use [webhook triggers](/harness-platform/3.0/harness-platform-resources/triggers/triggering-pipelines.md), you can get [Harness build statuses in your PRs](#pipeline-links-in-prs). However, you must configure your protection rules *in your SCM provider* if you want failed/running builds to block PR merges.

{% hint style="warning" %}
Failed pipelines don't inherently block PR merges. Harness can send pipeline statuses to your PRs, but you must configure branch protections and checks (such as protection rules, CODEOWNERS, linting, and other checks or restrictions) in your source control provider.
{% endhint %}

If you want to pull PR status check information into a Harness pipeline, such as to determine whether to run a specific step based on the outcome of a check, you can [add custom SCM status checks to your CI pipelines](#custom-scm-status-checks).

### SCM links in build details <a href="#scm-links-in-build-details" id="scm-links-in-build-details"></a>

When [viewing builds](/continuous-integration/3.0/use-harness-ci/use-harness-ci/viewing-builds.md) in Harness, builds triggered by webhooks can include a link to the PR or commit that started the build.

### Pipeline links in PRs <a href="#pipeline-links-in-prs" id="pipeline-links-in-prs"></a>

When viewing a PR in your SCM provider, if a manual or webhook build ran from that PR, then you can follow the **Details** link from the PR's Git status to the build details page in Harness. This is supported for both manual and webhook PR builds, but it is not supported for all SCM providers.

To get status updates in your PRs, you must:

1. [Configure a default codebase for your pipeline.](/continuous-integration/3.0/use-harness-ci/use-harness-ci/codebase-configuration/create-and-configure-a-codebase.md#configure-the-default-codebase) Your pipeline must have a Build stage. Build updates are only exported for Build stages.
2. Make sure you enable API access in your [code repo connector](/continuous-integration/3.0/use-harness-ci/use-harness-ci/codebase-configuration/create-and-configure-a-codebase.md#code-repo-connectors) settings.
3. Run PR builds. Branch and tag builds don't send PR status updates. You can use [webhook triggers](/harness-platform/3.0/harness-platform-resources/triggers/triggering-pipelines.md) to automatically run builds when PRs are created or updated.

{% hint style="info" %}
**CUSTOM STATUS CHECK NAMES**

You can customize the status check names that appear on your PRs by configuring the **Send status to Git** option in your pipeline stages. This allows you to use business-friendly names (like `Quality Gate` or `Security Scan`) instead of technical stage names. For more information, go to [Send Stage Execution Status to Git on Pull Requests](/harness-platform/3.0/harness-platform-resources/triggers/triggering-pipelines.md#send-stage-execution-status-to-git-on-pull-requests).
{% endhint %}

### Custom SCM status checks <a href="#custom-scm-status-checks" id="custom-scm-status-checks"></a>

If you want to pull PR status check information into a Harness pipeline, you can use [Run steps](/continuous-integration/3.0/use-harness-ci/use-harness-ci/run-step-settings.md) to query your SCM provider's API and include custom SCM status checks in your CI pipelines.

#### Add a custom status check <a href="#add-a-custom-status-check" id="add-a-custom-status-check"></a>

These steps explain how to add a status check that uses the GitHub API. For information about leveraging another SCM provider's API, refer to that provider's API documentation.

1. You need a [CI pipeline](/continuous-integration/3.0/use-harness-ci/use-harness-ci/prep-ci-pipeline-components.md) with a [Build stage](/continuous-integration/3.0/use-harness-ci/use-harness-ci/set-up-build-infrastructure/ci-stage-settings.md) where you'll add the **Run** step.
2. Create [GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) to use for authentication, and save the token as a [Harness text secret](/harness-platform/3.0/harness-platform-resources/secrets/add-use-text-secrets.md).
3. Add a [Run step](/continuous-integration/3.0/use-harness-ci/use-harness-ci/run-step-settings.md) to your **Build** (`CI`) stage.
4. Enter a **Name** for the step.
5. If required by your build infrastructure, provide the **Container Registry** and **Image**. For more information on how to set this up, please [look at the section below about Container Registry and Image](#container-registry-and-image)
   * **Container Registry** is a container registry connector, such as a Docker connector.
   * **Image** is the FQN or artifact name and tag of a Docker image that has cURL installed, such as `curlimages/curl:latest` for the [official cURL Docker Hub image](https://hub.docker.com/r/curlimages/curl).
   * To learn more about this setting and when it is required, [look at the section below about Container Registry and Image](#container-registry-and-image)
6. For **Shell**, select **Sh**.
7. In **Command**, enter a script that calls the GitHub API, for example:

   ```shell
   curl -i -X POST \
     -H "Authorization: Bearer <+secrets.getValue('account.YOUR_GITHUB_TOKEN_SECRET_ID')>" \
     -H "Accept: application/vnd.github.v3+json" \
     https://api.github.com/repos/YOUR_GITHUB_ORGANIZATION/<+pipeline.properties.ci.codebase.repoName>/statuses/<+codebase.commitSha> \
     -d '{"state":"pending","target_url":"<+pipeline.execution.url>","description":"Test is running","context":"harness-ci/tests"}'
   ```

   The above example calls the GitHub API and uses the GitHub token secret for authentication. It uses [expressions](/harness-platform/3.0/harness-platform-resources/variables-and-expressions/harness-variables.md) to pull information from the pipeline, such as the target repository name (`<+pipeline.properties.ci.codebase.repoName`>) and the pipeline build link (`<+pipeline.execution.url>`).

   If you use the above script, replace `YOUR_GITHUB_ORGANIZATION` with your GitHub organization name, and replace `YOUR_GITHUB_TOKEN_SECRET_ID` with the ID of the Harness text secret that contains your GitHub personal access token.
8. Configure additional settings as necessary for your script and build infrastructure. For example, you might want to set container resource limits, export output variables, or inject environment variables. For more information about **Run** step settings, go to [Use Run steps](/continuous-integration/3.0/use-harness-ci/use-harness-ci/run-step-settings.md).

The above script is a basic GitHub status check. You can modify the script to include more commands, get other information from the payload, or call a different SCM provider's API. For example, the following script takes different actions depending on the resulting status, and it includes environment variables and [conditional execution settings](/harness-platform/3.0/harness-platform-resources/overview/strategy/conditional-execution.md):

```shell
# status="<+execution.steps.STEP_ID.status>"
# name="harness-ci/tests"

echo "Send Commit Status"

if [[ "$status" == "SUCCEEDED" ]]; then
  state="success"
  description="$name scan passed for <+pipeline.properties.ci.codebase.repoName>"
elif [[ "$status" == "PENDING" ]]; then
  state="pending"
  description="$name scan pending for <+pipeline.properties.ci.codebase.repoName>"
else
  state="failure"
  description="$name scan failed for <+pipeline.properties.ci.codebase.repoName>"
fi

curl -i -u YOUR_GITHUB_ORGANIZATION:<+secrets.getValue("account.YOUR_GITHUB_TOKEN_SECRET_ID")> \
  -X POST \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/YOUR_GITHUB_ORGANIZATION/<+pipeline.properties.ci.codebase.repoName>/statuses/<+codebase.commitSha> \
  -d "{\"state\":\"$state\",\"target_url\":\"<+pipeline.execution.url>\",\"description\":\"$description\",\"context\":\"$name\"}"
```

#### Create reusable status check steps <a href="#create-reusable-status-check-steps" id="create-reusable-status-check-steps"></a>

If you want to include status checks in multiple pipelines, you might want to create reusable templates or plugins.

{% tabs %}
{% tab title="Create a step template" %}
[Step templates](/harness-platform/3.0/harness-platform-resources/templates-overview/v1-step-template.md) help you quickly reuse customized or complex steps in multiple pipelines. For example, here is a YAML example of a step template for a GitHub status check step:

```yaml
template:
  name: Send GitHub Status
  type: Step
  projectIdentifier: YOUR_HARNESS_PROJECT_ID
  orgIdentifier: YOUR_HARNESS_ORGANIZATION_ID
  spec:
    type: Run
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: curlimages/curl:7.82.0
      shell: Sh
      command: |+
        # status="<+execution.steps.STEP_ID.status>"
        # name="harness-ci/tests"

        echo "Send Commit Status"

        if [[ "$status" == "SUCCEEDED" ]]; then
          state="success"
          description="$name scan passed for <+pipeline.properties.ci.codebase.repoName>"
        elif [[ "$status" == "PENDING" ]]; then
          state="pending"
          description="$name scan pending for <+pipeline.properties.ci.codebase.repoName>"
        else
          state="failure"
          description="$name scan failed for <+pipeline.properties.ci.codebase.repoName>"
        fi

        curl -i -u YOUR_GITHUB_ORGANIZATION:<+secrets.getValue("account.YOUR_GITHUB_TOKEN_SECRET_ID")> \
          -X POST \
          -H "Accept: application/vnd.github.v3+json" \
          https://api.github.com/repos/YOUR_GITHUB_ORGANIZATION/<+pipeline.properties.ci.codebase.repoName>/statuses/<+codebase.commitSha> \
          -d "{\"state\":\"$state\",\"target_url\":\"<+pipeline.execution.url>\",\"description\":\"$description\",\"context\":\"$name\"}"

      envVariables:
        status: <+input>
        name: <+input>
      imagePullPolicy: IfNotPresent
    when:
      stageStatus: Success
      condition: <+codebase.build.type>=="PR"
  identifier: Send_Git_Status
  versionLabel: 1.0.0
```

{% endtab %}

{% tab title="Write a custom plugin" %}
You can package your status check script in a [custom plugin](/continuous-integration/3.0/use-harness-ci/use-harness-ci/use-drone-plugins/custom-plugins.md) and then add it to your pipelines in a [Plugin step](/continuous-integration/3.0/use-harness-ci/use-harness-ci/use-drone-plugins/custom-plugins.md#add-the-plugin-step).
{% endtab %}
{% endtabs %}

#### Container Registry and Image <a href="#container-registry-and-image" id="container-registry-and-image"></a>

The build environment must have the necessary binaries for the **SCM Status Checks**. Depending on the stage's build infrastructure, **SCM Status Checks** steps can use binaries that exist in the build environment, or use **Container Registry** and **Image** to pull an image, such as a public or private Docker image, that contains the required binaries.

### Troubleshoot status checks <a href="#troubleshoot-status-checks" id="troubleshoot-status-checks"></a>

Go to the [Harness CI Knowledge Base](/continuous-integration/3.0/troubleshooting-and-resources/ci-articles-and-faqs/continuous-integration-faqs.md) for common questions and issues related to codebases and SCM status checks, such as:

* [Failed pipelines don't block PR merges.](/continuous-integration/3.0/troubleshooting-and-resources/ci-articles-and-faqs/continuous-integration-faqs.md#failed-pipelines-dont-block-pr-merges)
* [Pipeline status updates aren't sent to PRs.](/continuous-integration/3.0/troubleshooting-and-resources/ci-articles-and-faqs/continuous-integration-faqs.md#pipeline-status-updates-arent-sent-to-prs)
* [Build statuses don't show on my PRs, even though the code base connector's token has all repo permissions.](/continuous-integration/3.0/troubleshooting-and-resources/ci-articles-and-faqs/continuous-integration-faqs.md#build-statuses-dont-show-on-my-prs-even-though-the-code-base-connectors-token-has-all-repo-permissions)
* [Why does the status check for my GitHub PR redirect to a different PR's build in Harness CI?](/continuous-integration/3.0/troubleshooting-and-resources/ci-articles-and-faqs/continuous-integration-faqs.md#why-does-the-status-check-for-my-pr-redirect-to-a-different-prs-build-harness)

For troubleshooting information for Git event (webhook) triggers, go to [Troubleshoot Git event triggers](/harness-platform/3.0/harness-platform-resources/triggers/triggering-pipelines.md#troubleshoot-git-event-triggers).

{% @harness-feedback/feedback %}
