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

# Jenkins

> Connect Jenkins so Gitar can read build logs and analyze failures

export const ThemeImage = ({src, alt, width}) => {
  let lightSrc, darkSrc;
  if (src.includes("-light.")) {
    lightSrc = src;
    darkSrc = src.replace("-light.", "-dark.");
  } else if (src.includes("-dark.")) {
    darkSrc = src;
    lightSrc = src.replace("-dark.", "-light.");
  } else {
    lightSrc = src;
    darkSrc = src;
  }
  const style = width ? {
    maxWidth: width,
    marginInline: "auto"
  } : undefined;
  return <span>
      <img className="block dark:hidden rounded-lg border" src={lightSrc} alt={alt} style={style} />
      <img className="hidden dark:block rounded-lg border" src={darkSrc} alt={alt} style={style} />
    </span>;
};

Gitar integrates with **GitHub Actions** and **GitLab Pipelines** with no setup. Jenkins needs two things from you: a user and API token that can read builds, and a Jenkins URL we can reach.

Jenkins reports a build to the pull request as a status, and that status links back to the build. Gitar reads the link, downloads the build log, and analyzes from there. There is no plugin to install for this. The console log is a core Jenkins endpoint.

## Prerequisites

* Jenkins already reporting build results to your pull requests. Multibranch pipelines using the [GitHub Branch Source](https://plugins.jenkins.io/github-branch-source/) plugin do this with no extra configuration, and other jobs need the **Set GitHub commit status** publisher from the [GitHub](https://plugins.jenkins.io/github/) plugin
* A Jenkins URL Gitar can reach. See [Network access](/connecting-code/network-access) if your controller is only reachable inside your network
* Permission to create a user and grant it read access, if you want a dedicated one for Gitar

## Setup

<Steps>
  <Step title="Create an API token">
    Sign in as the user you want Gitar to read as, open the user menu, and go to **Configure -> API Token -> Add new Token**. Name it something like `Gitar`, generate it, and copy it immediately. Jenkins does not show it again.

    A token carries the permissions of the user who made it, so make it as a user whose access matches what Gitar should see.

    <Note>
      Jenkins has no bearer-token mode. The token is the password half of HTTP Basic authentication, so it only works paired with its username, which is why Gitar asks for both.
    </Note>
  </Step>

  <Step title="Give that user read access">
    Grant **Overall/Read**, plus **Job/Read** on the jobs whose builds Gitar should read. Reading a job carries reading its console log, which is the entire permission set Gitar needs.

    A dedicated user scoped to a subset of jobs is the narrower grant, and it survives people leaving in a way a personal token does not.
  </Step>

  <Step title="Check the Jenkins URL">
    In **Manage Jenkins -> System**, confirm **Jenkins URL** is the address Gitar can reach your controller at, including any context path such as `https://example.com/jenkins`.

    This is the setting most worth checking. Every build link Jenkins publishes is built from it, so a Jenkins URL still set to `localhost` or an internal-only name publishes links nothing outside your network can open.
  </Step>

  <Step title="Connect Jenkins in Gitar">
    1. Navigate to your Gitar organization settings
    2. Go to the **Integrations** section
    3. Find the **Jenkins** integration and click **"Connect"**
    4. Enter the login of the user that created the token into **Jenkins Username**
    5. Paste the token into **Jenkins API Token**
    6. Set **Jenkins URL** to the same value you confirmed in the previous step

    <ThemeImage src="/assets/images/conn-jenkins-light.png" alt="Jenkins integration form with the username, API token and Jenkins URL" />

    <Note>
      Log fetching reads the server from the build link Jenkins posts, and checks it against the Jenkins URL you set here. A status pointing at some other host is left alone, which is what keeps your credentials from being sent somewhere you did not name.

      Jenkins has no hosted form, so unlike other CI providers this field is required. Leaving it blank means no logs are fetched rather than defaulting to anything.
    </Note>
  </Step>
</Steps>

## Two plugins that improve the results

Neither is required, and both are used automatically when present.

| Plugin                                                                  | What it adds                                                                                                                                                             |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Pipeline: Stage View](https://plugins.jenkins.io/pipeline-stage-view/) | Gitar reads the failing stage's log instead of the whole console. On a large monorepo build this is the difference between the failure and a hundred megabytes around it |
| [JUnit](https://plugins.jenkins.io/junit/)                              | Failing test names and their assertion messages are read alongside the log, so the analysis starts from the test rather than inferring it                                |

Without either, Gitar downloads the whole console log, which works everywhere.

## What Gitar reads

On a failing build, Gitar downloads that build's log and hands it to CI failure analysis. A green build is left alone. Nothing is written back to Jenkins, Gitar comments on the pull request instead.

See [CI failure analysis](/features/ci-failure-analysis) for what happens with those logs.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Gitar says nothing about a failed build">
    Open the pull request and look for a Jenkins status check, usually named `continuous-integration/jenkins/pr-head` or `pr-merge`. No status means Jenkins never told your Git provider the build ran, which is Jenkins-side configuration.

    For a multibranch pipeline, that is the [GitHub Branch Source](https://plugins.jenkins.io/github-branch-source/) plugin and the credential it uses, which needs permission to write statuses on the repository. For other jobs it is the **Set GitHub commit status** publisher.

    If the status is there and Gitar still stayed quiet, check that **Jenkins URL** matches the host in the status link. A mismatch drops the event.
  </Accordion>

  <Accordion title="The status link opens nothing, or opens an internal address">
    **Manage Jenkins -> System -> Jenkins URL** is what every link is built from. If you browse Jenkins at one address and it publishes another, this is the setting to correct, and it takes effect on the next build rather than retroactively.
  </Accordion>

  <Accordion title="Log fetching fails on a build that exists">
    The credentials resolve but the user cannot see the job. Grant **Job/Read** on that job and no new token is needed, permissions being evaluated per request.

    A wrong username looks identical to a wrong token, since HTTP Basic authentication fails the same way either way. Confirm the username is the user's login rather than their display name.
  </Accordion>

  <Accordion title="A branch name contains a slash">
    Nothing to do. Jenkins encodes those in build URLs and Gitar reads them as published, so `feature/my-branch` works the same as any other branch.
  </Accordion>

  <Accordion title="Jenkins is on a private network">
    A controller reachable only over a VPN, PrivateLink or an internal-only domain cannot be read from Gitar's side. Reach out and we will wire up network access.

    See [Network access](/connecting-code/network-access) for the general shape of this.
  </Accordion>
</AccordionGroup>

## Security notes

* Credentials are encrypted and stored in AWS Secrets Manager
* Prefer a dedicated user's token over a personal one, so access survives people leaving
* Overall/Read and Job/Read are read-only, and Gitar writes nothing to Jenkins. Grant nothing wider
* Scope Job/Read to the jobs Gitar should read if the whole controller is more than you want to grant
* The Jenkins URL you set is checked against every build link before any credential is used, so a status naming a different host is ignored
* Revoke the token from the user's **Configure** page at any time to cut off access

## Jenkins references

| Topic                                    | Jenkins docs                                                                                                              |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| API tokens                               | [Authenticating scripted clients](https://www.jenkins.io/doc/book/system-administration/authenticating-scripted-clients/) |
| Permissions                              | [Authorization](https://www.jenkins.io/doc/book/security/managing-security/#authorization)                                |
| Reporting build status to a pull request | [GitHub Branch Source](https://plugins.jenkins.io/github-branch-source/)                                                  |
| The URL every build link is built from   | [Jenkins URL](https://www.jenkins.io/doc/book/security/services/#jenkins-url)                                             |
