Repo Jenkins library

Rebo jenkins lib is shared library for Jenkins that helps with basic operations with Gerrit over git and repo managed projects.

source: https://gitea.amarulasolutions.com/i-tools/repo_jenkins_lib

source: https://gerrit-review.amarulasolutions.com/admin/repos/i-tools/repo_jenkins_lib

configured as:

  • name: repo_jenkins_lib

  • load implicitly: true

  • allow default version to be overridden: true

Installation

Add the repository to your Jenkins instance as Shared library:

  1. go to “Manage Jenkins” > “Configure System”

  2. scroll down to “Global Pipeline Libraries” section

  3. use “Add”

    1. Name: repo_jenkins_lib

    2. Default version: master

    3. Retrieval method → Modern SCM

      1. Source Code Management → Git

      2. Project Repository: ssh://gitea@gitea.amarulasolutions.com:38745/i-tools/repo_jenkins_lib.git

  4. “Save”

Generate password for Gerrit REST API

Create password for your Gerrit bot user and add it to Jenkins. You can use gerrit REST API to generate the password:

curl -X PUT \
    --user <admin username>:<admin password> \
    --header "Content-Type: application/json; charset=UTF-8" \
    -d "{\"generate\": true}" \
    https://gerrit-review.amarulasolutions.com/a/accounts/<gerrit bot user id>/password.http

Add the credentials to Jenkins:

  1. go to “Credentials” -> “System”

  2. use “Add Credentials”

    • Kind: “Username with password”

    • Username: gerrit bot username

    • Password: gerrit bot REST API password

    • ID: e.g. jenkins-builder-amarula_gerrit-rest-api

    • Description: …

  3. “Save”

Optional installation steps

Optionally you can fork repo tool and use your own stable version by defining “REPO_URL” and “REPO_BRANCH” in Jenkins Global Variables.

Library description

Main classes

This is only a brief description of the classes. See the specific class page for more details.

com.amarula.git.Git

Helper class for basic git operations. It can sync given tag/branch or checkout/cherry-pick Gerrit change from the given parameters.

com.amarula.gerrit.Gerrit

Helper class for basic Gerrit operations. It is used internally to query changes and set review labels in Gerrit.

com.amarula.gerrit.GerritChange

Represents single Gerrit change with enough information to fetch the change or set review labels.

com.amarula.repo.Repo

Helper class for repo managed projects. It is used to sync projects including checkout/cherry-pick of Gerrit changes or Gerrit topics.

Typical use

Repo project verification

The example below show typical use-case of repo project verification. The pipeline fetches all relevant changes with the same topic and sets a review to them.

The variable ‘env.GERRIT_TOPIC’ used in the example below is automatically set by Gerrit Trigger Plugin or can be set as Job Parameter.

 Click here to see the example code …

@Library('repo_jenkins_lib')
import com.amarula.gerrit.GerritChange
import com.amarula.repo.Repo

node {
  stage('Repo init and sync') {
    def changes = []
    def value = GerritChange.FAILURE
    sh "git config --global user.email ${env.GERRIT_USER_EMAIL}"
    sh "git config --global user.name ${env.GERRIT_USER_NAME}"
    withCredentials([usernamePassword(
        credentialsId: 'jenkins-builder-amarula_gerrit-rest-api',
        passwordVariable: 'GERRIT_RESTAPI_PASS',
        usernameVariable: 'GERRIT_RESTAPI_USER')]) {
      try {
        def repo = new Repo(this, env,
            'ssh://gitea@gitea.amarulasolutions.com:38745/myAndroidProject/manifest.git')
        sshagent(['someCredentialId1', 'someCredentialId2']) {
          // repo init
          repo.init()

          // checkout topic changes for manifest (OPTIONAL: default manifest will be used to sync)
          changes.addAll(repo.checkoutTopicForManifest(env.GERRIT_TOPIC))

          // repo sync
          repo.sync()

          // checkout topic changes for projects (OPTIONAL)
          changes.addAll(repo.checkoutTopic(env.GERRIT_TOPIC))

          // build project
          sh 'make'

          value = GerritChange.SUCCESS
        }
      } finally {
        for (change in changes) {
          change.setVerified(value)
        }
      }
    }
  } /* END 'Repo init and sync' */
}

Repo project test build

The next example shows another typical use-case of test build with cherry-picking some changes.

 Click here to see the example code …

@Library('repo_jenkins_lib')
import com.amarula.gerrit.GerritChange
import com.amarula.repo.Repo

node {
  stage('Repo init and sync') {
    def changes = []
    sh "git config --global user.email ${env.GERRIT_USER_EMAIL}"
    sh "git config --global user.name ${env.GERRIT_USER_NAME}"
    withCredentials([usernamePassword(
        credentialsId: 'jenkins-builder-amarula_gerrit-rest-api',
        passwordVariable: 'GERRIT_RESTAPI_PASS',
        usernameVariable: 'GERRIT_RESTAPI_USER')]) {

      def repo = new Repo(this, env,
          'ssh://gitea@gitea.amarulasolutions.com:38745/myAndroidProject/manifest.git')
      sshagent(['someCredentialId1', 'someCredentialId2']) {
        // repo init
        repo.init()

        // cherry-pick topic changes for manifest (OPTIONAL: default manifest will be used to sync)
        changes.addAll(repo.cherrypickTopicForManifest(env.GERRIT_TOPIC))

        // repo sync
        repo.sync()

        // cherry-pick topic changes for projects (OPTIONAL)
        changes.addAll(repo.cherrypickTopic(env.GERRIT_TOPIC))

    echo "Building with topic: ${env.GERRIT_TOPIC}"
    echo "Applied changes: ${changes}"

        // build project
        sh 'make'
      }
    }
  } /* END 'Repo init and sync' */
}

Git project test build

This example shows usage of the Git class. The example shows how to checkout a specific Gerrit change given by env.GERRIT_REFSPEC from myProject repository and checkout repository with support tools myProjectSupportTools in one line.

The GERRIT_REFSPEC is initialized by the Gerrit Trigger Plugin or can be set from Job Parameters.

 Click here to see the example code …

@Library('repo_jenkins_lib')
import com.amarula.gerrit.GerritChange
import com.amarula.git.Git

node {
  def change
  def myProject

  stage('Project sync') {
    sh "git config --global user.email ${env.GERRIT_USER_EMAIL}"
    sh "git config --global user.name ${env.GERRIT_USER_NAME}"
    withCredentials([usernamePassword(
        credentialsId: 'jenkins-builder-amarula_gerrit-rest-api',
        passwordVariable: 'GERRIT_RESTAPI_PASS',
        usernameVariable: 'GERRIT_RESTAPI_USER')]) {
      myProject = new Git(this, env,
          'ssh://gitea@gitea.amarulasolutions.com:38745/myProject',
          [gerritRemoteUrl:'https://gerrit-review.amarulasolutions.com'])

      sshagent(['someCredentialId1', 'someCredentialId2']) {
        change = myProject.checkoutChange(env.GERRIT_REFSPEC)

        new Git(this, env, 'ssh://gitea@gitea.amarulasolutions.com:38745/myProjectSupportTools').sync()
      }
  }

  stage('Build') {
    def result = GerritChange.FAILURE
    try {
      dir(myProject.getDirectory()) {
        sh 'make'
      }
      result = GerritChange.SUCCESS
    } finally {
      withCredentials([usernamePassword(
          credentialsId: 'jenkins-builder-amarula_gerrit-rest-api',
          passwordVariable: 'GERRIT_RESTAPI_PASS',
          usernameVariable: 'GERRIT_RESTAPI_USER')]) {
        change.setVerified(result)
      }
    }
  }
}