# Jenkins

Integrating Jenkins with Hivel allows you to gain data-driven insights into your development workflow. Follow these steps to set up the integration correctly.

### **System Requirements**

Before proceeding, ensure the following:\
✅ You have **Admin access** to Jenkins. *(Preferably, a DevOps engineer should handle this)*

**Check if the below plugins are installed on Jenkins. If not, install them.**

<table data-header-hidden><thead><tr><th></th><th width="238"></th><th></th><th></th></tr></thead><tbody><tr><td>Plugin Name</td><td>Description</td><td>Link</td><td>Status</td></tr><tr><td>HTTP Request Plugin</td><td>Enables making HTTP requests within Jenkins pipelines.</td><td><a href="https://plugins.jenkins.io/http_request/">HTTP Request | Jenkins plugin</a></td><td>Need to install</td></tr><tr><td>Timestamper Plugin</td><td>Adds timestamps to Jenkins build logs for better debugging.</td><td><a href="https://plugins.jenkins.io/timestamper/">Timestamper | Jenkins plugin</a></td><td>Need to install</td></tr><tr><td>Pipeline (Workflow Aggregator)</td><td>Provides the essential pipeline functionality in Jenkins.</td><td><a href="https://plugins.jenkins.io/workflow-aggregator/">Pipeline | Jenkins plugin</a></td><td>Mostly Already installed</td></tr><tr><td>Git Plugin</td><td>Enables Jenkins to fetch and manage source code from Git repositories.</td><td><a href="https://plugins.jenkins.io/git/">Git | Jenkins plugin</a></td><td>Mostly Already installed</td></tr><tr><td>Credentials Binding Plugin</td><td>Allows securely storing and using credentials in Jenkins pipelines.</td><td><a href="https://plugins.jenkins.io/credentials-binding/">Credentials Binding | Jenkins plugin</a></td><td>Mostly Already installed</td></tr><tr><td>Groovy Plugin</td><td>Allows running Groovy scripts within Jenkins.</td><td><a href="https://plugins.jenkins.io/groovy/">Groovy | Jenkins plugin</a></td><td>Mostly Already installed</td></tr></tbody></table>

**How to Install These Plugins:**

1. Go to **Manage Jenkins → Manage Plugins → Available Plugins**.
2. Search for the plugins listed above and install them.
3. Restart Jenkins after installation (if prompted).

### **Required Credentials for Integration**

During the integration, you'll need:

* **Organization ID** (Generated in the Hivel application)
* **API Key** (Generated in the Hivel application)

### Retrieving Your Organization ID and API Key

1. Open the Hivel application and navigate to **Integrations** under the **Settings**.
2. Locate the Jenkins Integration card and click **Connect**.<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcZYmHucOE6nqrdMPazoVFZu-2by7ZZRz5pw6U72JOU-3o6uwVU_5p9pZnk_SZ1qicp8BS2u825cIjAvYuPfVhz_kLN_EtVuiBbgodCbT03dwU9uPjxMIQc4oQ68HHC3R8CL66O1w?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="188"><figcaption></figcaption></figure>
3. Follow the given steps to start your integration.<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdFDwkQcmeDCx88WyPCRtUng-239XHII5rHC6lD1Gxgb87qXLsjMSyLZyYEovZ4nbjkkGWGiyKk3QkJ8_4AVbzrOYNmtQ7Q1v5_nSPsU0zFPndGMxs-vzQkgfG-piYsoz-akJAkDA?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="375"><figcaption></figcaption></figure>
4. By clicking on generate your **Organization ID** and **API Key** will be generated.<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXc4tfb0nUfcb7DYhWE1bhXNm18Z8Vz3DRC13PWMrbPH72uuUdTPYM1EcKHe5G4aMonV1OxmrYfUm2bDvzOrf2jYGuKNhTu0BJ8vYqAyVKM3L71taOLTgqHjJPDzxO2Gm55ycZdjqg?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="375"><figcaption></figcaption></figure>
5. Use these fields while integrating with Jenkins. The steps for where to apply them are provided on the following page.&#x20;
6. If you find it difficult, don’t worry! You can always reach out to us for assistance at [<mark style="color:purple;">support@hivel.ai</mark>](mailto:support@hivel.ai).

### Configuring Credentials in Jenkins

1. Log in to your Jenkins application.
2. From the side navigation, select **Manage Jenkins**.<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXc7Zq7YEYzRD-WXeVGhLXREZ0x-wPNePtZV2Y96aQzAZFGMl_EIvlNQH9prvjv572f47Sa9F-83dLSjfHKbWtDSr7cPTV4KtauVs9Ka1wlMUVzjE52uefqJ5ep8EweRFW48qHLJxg?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="188"><figcaption></figcaption></figure>
3. Click on **Credentials**.<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXffr4HxN9iKLh6eDudRikfP5RybAw1E-yIAfhdJOJubPXugW0xbAajKpYunI_W_SDHg05fyTZU8N47NCiLFhkzQ1vb_buv8NsyHT6QYekGkhDd3pwqiNEVQZCHnos6QzzjyHHQc?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="563"><figcaption></figcaption></figure>
4. Click on **global** under **Stores scoped to Jenkins**<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdwGJ-s8Anoz78DyD3pVVk3u7vDQhi8cE_iMTQs-5S-CU6bjN4ZyQ6GLNLCEVr8Jc8X9pJAtydp9-GcshQlm2iohWLd6Q8BkiAZQ_z6SnamHBkdspuF86xKxvZxk0oDxX5DSv1KZQ?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="563"><figcaption></figcaption></figure>
5. Choose **Add Credentials** - you will need to do this **twice** (once for the **Organization ID** and once for the **API Key**).<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXflHCv0b6EEEdh_7QRCFuPuaxkoLWeoAV2Y2aQSXrC1JrXfx-r-JV_2WL5fmDfDLvVqW48CvgpdeyZHgVLfpK77ASSbOm1Mt4cYoT-luyzJMB6168R9dyRR8FYUCVQqNAz00SftnA?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="563"><figcaption></figcaption></figure>
6. From the dropdown, select **Secret text**.<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfkFiohkzASOjDeYAK7CRjetdJpMX7szdwBuBwiOlRFW2RZex0NRmb8dmyly0tXLj2HhkefIRtRnGzj1e84pWjcakRqXl-tYE1azMtd9SHJ7BsozEZEc3Kqvz1E9q2V0XeAmD79yw?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt="" width="563"><figcaption></figcaption></figure>
7. After selecting Secret text from the dropdown, fill in the details twice as follows:
   1. &#x20;**Adding the API Key**
      1. **ID**: <mark style="color:green;">hivel-jenkins-api-key</mark>
      2. **Secret**: <mark style="color:green;">{your API key}</mark> (copied from Hivel)
      3. **Description**: This is the Jenkins API key from Hivel
      4. Click **Save**
   2. **Repeat the process again for Adding the Organization ID**
      1. **ID**: <mark style="color:green;">hivel-org-id</mark>
      2. **Secret**: <mark style="color:green;">{your Organization ID}</mark> (copied from Hivel)
      3. **Description**: This is the Jenkins Organization ID from Hivel
      4. Click **Save**
8. Once you have completed the above steps, your Jenkins Global Credentials should display the following entries:<br>

   <figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfWdtQhOLtex0MnuuSI0ZzdObsS2ND_SoptxoJJqAwFBwiXfE7cBRtijuz07ZPiU3R26HTqWV_FMG-DgoGaBdud3ezSoQR-FeDLhRCfMSvu4Oe49cHdWUV6ZKAqmtsiBbaALk9tUQ?key=GGAZqg4Zxvg8E9x8twDGRtGG" alt=""><figcaption></figcaption></figure>

### Changes to pipeline script

1. Go to Dashboard
2. Select any pipeline->**Configure**->**Edit Pipeline**

In the pipeline script, add the following:

```javascript
environment {
    WEBHOOK_URL = 'https://app.hivel.ai/insightlyapi/webhook/jenkins'
    ORG_ID = credentials('hivel-org-id')        // Organization ID from Hivel
    API_KEY = credentials('hivel-jenkins-api-key')  // API Key from Hivel
}
```

And this to your pipeline initialization code:

```javascript
stage('Initialize') {
    steps {
        script {
            // For build duration tracking
            env.BUILD_START_TIME = System.currentTimeMillis()
            
            // For stage metrics collection
            stageData = []
        }
    }
}
```

#### How to Wrap Your Stage Code for Metrics Collection

For each additional stage you add, ensure you wrap your existing commands with the following snippet. This wrapping captures the start time, end time, duration, and status of the stage:

```javascript
def stageStart = System.currentTimeMillis()
try {
    // Your stage commands here.
    def stageEnd = System.currentTimeMillis()
    stageData.add([
        stage_name: "Your Stage Name",
        start_time: new Date(stageStart).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
        end_time:   new Date(stageEnd).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
        duration:   ((stageEnd - stageStart) / 1000) as int,
        status:     "SUCCESS"
    ])
} catch (Exception e) {
    def stageEnd = System.currentTimeMillis()
    stageData.add([
        stage_name: "Your Stage Name",
        start_time: new Date(stageStart).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
        end_time:   new Date(stageEnd).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
        duration:   ((stageEnd - stageStart) / 1000) as int,
        status:     "FAILED",
        error_message: e.getMessage()
    ])
    throw e
}
```

* Insert your stage commands where indicated.
* This snippet ensures that each stage’s metrics are captured and included in the final payload sent to Hivel.

#### API call from Jenkins

Add the below code after each stage:&#x20;

```javascript
post {
        always {
            script {
                // Capture overall build end time and calculate total build duration
                def buildEndTime = System.currentTimeMillis()
                def buildStartTime = env.BUILD_START_TIME.toLong()
                
                // Retrieve Git information from scmVarsData if available; fallback to shell commands if not.
                def branchName = scmVarsData?.GIT_BRANCH ?: sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true).trim()
                def commitID   = scmVarsData?.GIT_COMMIT ?: sh(script: "git rev-parse HEAD", returnStdout: true).trim()
                
                // Construct the payload with build metrics and stage data for Hivel integration
                def payload = [
                    org_id      : env.ORG_ID.toInteger(),
                    job_name    : env.JOB_NAME,
                    build_number: env.BUILD_NUMBER.toInteger(),
                    status      : currentBuild.result ?: 'SUCCESS',
                    build_url   : env.BUILD_URL,
                    start_time  : new Date(buildStartTime).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                    end_time    : new Date(buildEndTime).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                    duration    : ((buildEndTime - buildStartTime) / 1000) as int,
                    git         : [
                        commit         : commitID,
                        branch         : branchName,
                        author         : sh(script: "git log -1 --pretty=format:'%an'", returnStdout: true).trim(),
                        author_email   : sh(script: "git log -1 --pretty=format:'%ae'", returnStdout: true).trim(),
                        commit_message : sh(script: "git log -1 --pretty=format:'%s'", returnStdout: true).trim(),
                        repository     : sh(script: "git config --get remote.origin.url", returnStdout: true).trim()
                    ],
                    triggered_by: sh(script: "git log -1 --pretty=format:'%ae'", returnStdout: true).trim(),
                    node        : env.NODE_NAME,
                    jenkins_version: sh(script: "jenkins --version || echo 'Unknown'", returnStdout: true).trim(),
                    stages      : stageData
                ]
                
                // Convert the payload to JSON format
                def payloadJson = groovy.json.JsonOutput.toJson(payload)
                echo "Payload: ${payloadJson}"
                
                // Send the payload to the Hivel endpoint using the httpRequest step
                httpRequest(
                    url: env.WEBHOOK_URL,
                    httpMode: 'POST',
                    contentType: 'APPLICATION_JSON',
                    customHeaders: [[name: 'X-API-Key', value: env.API_KEY]],
                    requestBody: payloadJson,
                    ignoreSslErrors: true
                )
            }
        }
    }
```

{% tabs %}
{% tab title="Sample Script" %}
Once the code wrapping is done, your code will look similar to the sample script in the [next tab](#sample-script-1).
{% endtab %}

{% tab title="Sample Script" %}

```javascript
pipeline {
    agent any

    environment {
        // Hivel Integration configuration
        WEBHOOK_URL = 'https://app.hivel.ai/insightlyapi/webhook/jenkins'
        ORG_ID      = credentials('hivel-org-id')        // Your Hivel Organization ID
        API_KEY     = credentials('hivel-jenkins-api-key') // Your Hivel API Key
    }

    stages {
        // -------------------------------
        // Stage: Initialize
        // -------------------------------
        stage('Initialize') {
            steps {
                script {
                    // Capture overall build start time and initialize a list for stage metrics
                    env.BUILD_START_TIME = System.currentTimeMillis()
                    stageData = []
                }
            }
        }

        // -------------------------------
        // Stage: Checkout Code
        // -------------------------------
        stage('Checkout Code') {
            steps {
                script {
                    // Capture the start time for the Checkout stage
                    def stageStart = System.currentTimeMillis()
                    try {
                    
                        // Checkout the repository using Git; credentials and branch are specified here.
                        // The returned data (e.g., branch and commit information) is stored in 'scmVarsData'
                        scmVarsData = checkout([
                            $class: 'GitSCM',
                            branches: [[name: 'dev']],
                            userRemoteConfigs: [[
                                url: 'https://gitlab.com/my-org/hello-world.git', 
                                credentialsId: 'gitlab-token'
                            ]]
                        ])
                        
                        def stageEnd = System.currentTimeMillis()
                        // Record stage metrics as SUCCESS
                        stageData.add([
                            stage_name: "Checkout Code",
                            start_time: new Date(stageStart).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                            end_time:   new Date(stageEnd).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                            duration:   ((stageEnd - stageStart) / 1000) as int,
                            status:     "SUCCESS"
                        ])
                    } catch (Exception e) {
                        def stageEnd = System.currentTimeMillis()
                        // Record stage metrics as FAILED and capture the error message
                        stageData.add([
                            stage_name: "Checkout Code",
                            start_time: new Date(stageStart).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                            end_time:   new Date(stageEnd).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                            duration:   ((stageEnd - stageStart) / 1000) as int,
                            status:     "FAILED",
                            error_message: e.getMessage()
                        ])
                        // Rethrow the exception to mark the build as failed
                        throw e
                    }
                }
            }
        }

        // -------------------------------
        // Add additional stages below as required for your pipeline...
        // For example, you might add stages for building, testing, or deploying:
        // stage('Build') { ... }
        // stage('Test') { ... }
        // stage('Deploy') { ... }
    }

    post {
        always {
            script {
                // Capture overall build end time and calculate total build duration
                def buildEndTime = System.currentTimeMillis()
                def buildStartTime = env.BUILD_START_TIME.toLong()
                
                // Retrieve Git information from scmVarsData if available; fallback to shell commands if not.
                def branchName = scmVarsData?.GIT_BRANCH ?: sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true).trim()
                def commitID   = scmVarsData?.GIT_COMMIT ?: sh(script: "git rev-parse HEAD", returnStdout: true).trim()
                
                // Construct the payload with build metrics and stage data for Hivel integration
                def payload = [
                    org_id      : env.ORG_ID.toInteger(),
                    job_name    : env.JOB_NAME,
                    build_number: env.BUILD_NUMBER.toInteger(),
                    status      : currentBuild.result ?: 'SUCCESS',
                    build_url   : env.BUILD_URL,
                    start_time  : new Date(buildStartTime).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                    end_time    : new Date(buildEndTime).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
                    duration    : ((buildEndTime - buildStartTime) / 1000) as int,
                    git         : [
                        commit         : commitID,
                        branch         : branchName,
                        author         : sh(script: "git log -1 --pretty=format:'%an'", returnStdout: true).trim(),
                        author_email   : sh(script: "git log -1 --pretty=format:'%ae'", returnStdout: true).trim(),
                        commit_message : sh(script: "git log -1 --pretty=format:'%s'", returnStdout: true).trim(),
                        repository     : sh(script: "git config --get remote.origin.url", returnStdout: true).trim()
                    ],
                    triggered_by: sh(script: "git log -1 --pretty=format:'%ae'", returnStdout: true).trim(),
                    node        : env.NODE_NAME,
                    jenkins_version: sh(script: "jenkins --version || echo 'Unknown'", returnStdout: true).trim(),
                    stages      : stageData
                ]
                
                // Convert the payload to JSON format
                def payloadJson = groovy.json.JsonOutput.toJson(payload)
                echo "Payload: ${payloadJson}"
                
                // Send the payload to the Hivel endpoint using the httpRequest step
                httpRequest(
                    url: env.WEBHOOK_URL,
                    httpMode: 'POST',
                    contentType: 'APPLICATION_JSON',
                    customHeaders: [[name: 'X-API-Key', value: env.API_KEY]],
                    requestBody: payloadJson,
                    ignoreSslErrors: true
                )
            }
        }
    }
}


```

{% endtab %}
{% endtabs %}

* Once the changes are done, click on Apply -> Save.
* **Repeat** the steps for each stage of your pipeline script. Please check the indentation while wrapping the code.
* **Run the build once changes are made to all the stages.**

#### These are the details we will be receiving from Jenkins upon successful integration:

{% tabs %}
{% tab title="API Details" %}
{% code overflow="wrap" %}

```markup
Base URL: https://app.hivel.ai/insightlyapi/webhook/jenkins
Method: POST
Headers:
    Content-Type: application/json
    X-API-Key: [API key from credentials]
```

{% endcode %}
{% endtab %}

{% tab title="Curl Request" %}

```javascript
curl --location \
--request POST 'https://app.hivel.ai/insightlyapi/webhook/jenkins' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: YOUR_API_KEY' \
--data-raw '{
    "org_id": 123,
    "job_name": "pipeline-job-name",
    "build_number": 45,
    "status": "SUCCESS",
    "build_url": "http://jenkins-url/job/pipeline-job-name/45",
    "start_time": "2024-02-06T10:00:00Z",
    "end_time": "2024-02-06T10:15:00Z",
    "duration": 900,
    "git": {
        "commit": "abc123def456",
        "branch": "dev",
        "author": "John Doe",
        "author_email": "john@example.com",
        "commit_message": "Feature update",
        "repository": "https://gitlab.com/myorganization/hello-world.git"
    },
    "triggered_by": "john@example.com",
    "node": "jenkins-node-1",
    "jenkins_version": "2.426.1",
    "stages": [
        {
            "stage_name": "Stage 1",
            "start_time": "2024-02-06T10:00:00Z",
            "end_time": "2024-02-06T10:05:00Z",
            "duration": 300,
            "status": "SUCCESS"
        },
        "...",
        {
            "stage_name": "Stage N",
            "start_time": "2024-02-06T10:10:00Z",
            "end_time": "2024-02-06T10:15:00Z",
            "duration": 300,
            "status": "SUCCESS"
        }
    ]
}'
```

{% endtab %}

{% tab title="Payload" %}
**Payload** **Fields** **Explanation**

* **org\_id**: Organization identifier (Integer)
* **job\_name**: Name of the Jenkins job
* **build\_number**: Jenkins build number
* **status**: Build status (e.g., "SUCCESS", "FAILED")
* **build\_url**: URL to access build details
* **start\_time**: Timestamp when the build started
* **end\_time**: Timestamp when the build completed
* **duration**: Build duration in seconds
* **git**: Git metadata object
  * commit: Latest commit hash
  * branch: Git branch name
  * author: Commit author name
  * author\_email: Commit author email
  * commit\_message: Commit message
  * repository: Git repository URL
* **triggered\_by**: Email of build trigger user
* **node**: Jenkins node name
* **jenkins\_version**: Jenkins server version
* **stages**: Array of stage objects
  * stage\_name: Name of pipeline stage
  * start\_time: Stage start timestamp
  * end\_time: Stage end timestamp
  * duration: Stage duration in seconds
  * status: Stage status
  * error\_message: Optional error description
    {% endtab %}
    {% endtabs %}

The integration is considered complete once the build is run, successfully processed, and the integration card updates to "**Connected"**.

If you need any support at any point, please feel free to reach out to us at [<mark style="color:purple;">**support@hivel.ai**</mark>](mailto:support@hivel.ai). We’re happy to assist you!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hivel.ai/integrations/ci-cd/jenkins.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
