(Step by step guide to Implement CI CD UiPath Using Jenkins Plugins)

In this article, I have tried to give a simplistic view of the integration required for the implementation of CI-CD tools- GIT and Jenkins with UiPath. A similar guide is already published for Azure Pipelines.

In this article, we have covered –

  1. Basic of Jenkins to get started
  2. Key Jenkins concepts to remember
  3. Install and configure UiPath Jenkins Plugin
  4. Building pipeline using Jenkins for Build, Test and Deploy
  5. Working example (Jenkins files)
  6. Further Improvements

Let’s get started!

Pre-requisites

  • You should have Jenkins server Up and Running (You can install fresh or Use existing …follow the installation step for windows as we need a window-based agent for UiPath)
  • UiPath should be installed in a machine that would be used for DevOps.
  • Your Source code should be kept in Version Control System (Such as Git, GitHub etc.…)
  • You should have administrative access on UiPath Orchestrator Instance.
  • You should have (Required User API Keys) for Orchestrator API access

Why Jenkins

Jenkins introduces a domain-specific language (DSL) based on ‘Groovy’, which can be used to define a new pipeline as a script.

  1. Using Jenkins Pipeline to automate CI/CD pipelines dramatically increases repeat-ability, reliability, efficiency, and quality.
  2. The Pipeline allows managing the process code like any other production code, facilitating iterative development for pipelines, along with access control, code review, audit trails, and a single source for truth that is review-able (and potentially an approval/promotion process) by multiple project members.
  3. Multi-branch pipelines are also possible to configure different jobs for different branches within a single project

Few Requirements to be considered

Similar to Azure UiPath Pipelines Example, we have two options to create our pipelines.

  1. You can use UiRobot.Exe (Or UiPath PowerShell Utility) to perform various tasks. This method will require you to write PowerShell snippet using cmdlet to perform tasks.
  2. You can use the “UiPath Jenkins Plugin” to perform the required Build, Test and Publish tasks… all you need to do is utilize “UiPathPack”, “UiPathTest” and “UiPathDeploy” with required configuration.
  3. You can create pipeline using the classic Jenkins UI to define your build and other stages …Or simply creating Jenkins File inside your source code to perform your task…

For this article, we are going to use the “UiPath Jenkins Plugin” to create pipelines using the “Jenkins File” kept inside project folder…

Why Using a Jenkinsfile

Jenkinsfile is a text file that contains the definition of a Jenkins Pipeline.The different organization has a different approach to building pipelines, however creating a Jenkinsfile, which is checked into source control provides below benefits –

  • As Pipelines continue to grow, it would be difficult to maintain them, by using the text area present in the Jenkins job configuration page only. A better option is to store them in specific files versioned within your project repository.
  • Complex Pipelines are difficult to write and maintain within the classic UI’s Script text area of the Pipeline configuration page.
  • You can review/add additional stages for pipelines
  • You should be able to have audit trails of pipeline changes inside the version control system
  • Jenkinsfile is not a replacement for existing build tools it only binds the multiple phases of project life cycle…Not only this it can be also utilized to perform various post-deployment actions.

Key Jenkins Pipeline concepts

[You can skip this section if you are already aware of basic terminologies of DevOps implementation]

As discussed above, the definition of a Jenkins Pipeline is written into a text file (called a Jenkinsfile) which in turn can be committed to a project’s source control repository.

The following concepts are key aspects of Jenkins Pipeline-

  1. Pipeline – A Pipeline’s code defines your entire integration and build process, which typically includes stages, steps for building an application, testing it and then delivering it.
  2. Node– A node is a machine which is part of the Jenkins environment and is capable of executing a Pipeline. (You can treat node as Agent which is configured and contains all the required tool to build your project.)
  3. Stages – A Stage Block logically separate the tasks performed through the entire process, for Example “Build”, “Test” and “Deploy” stages.
  4. Steps – A single task. Fundamentally, a step tells Jenkins what to do at a particular point in time (or “step” in the process).
  5. Directives – The environment directive specifies a sequence of key-value pairs which will be defined as environment variables for all steps, or stage-specific steps, depending on where the environment directive is located within the Pipeline.
  6. Post – The post section defines one or more additional steps that are run upon the completion of a Pipeline’s or stage’s run (depending on the location of the post section within the Pipeline). post can support any of the following post-condition blocks: always, changed, fixed, regression, aborted, failure, success, unstable, unsuccessful, and cleanup.

There are few other levels and options which are also required if you wish to create more complex example. You can read the syntax of Pipeline here. (Pipelines syntax)

Declarative versus Scripted Pipeline syntax

A Jenkins file (Pipeline) can be written in two types of syntax-

Declarative – is a relatively new addition to pipeline syntax and provide a simplified way to get started with the configuration to perform various steps.

(Imposes limitations to the user with a much stricter and pre-defined structure)

  • Its start within a pipeline block, for example, pipeline {/* Insert Details inside */}
  • It follows the same rules as Groovy’s syntax
  • Blocks must only consist of Sections, Directives, Steps, or assignment statements.

Scripted– Scripted Pipelines can include and make use of any valid Groovy code.

  • Scripted Pipelines are wrapped in a node block. Here a node refers to a system that contains the Jenkins agent pieces and can run jobs(example node{/* Insert Details here */} )
  • Most functionality provided by the Groovy language is made available to users of Scripted Pipeline, which means it can be a very expressive and flexible tool with which one can author continuous delivery pipelines.

Syntax Comparison:

  • Scripted Pipeline offers a tremendous amount of flexibility and extensibility to Jenkins users. The Groovy learning-curve isn’t typically desirable for all members of a given team, so Declarative Pipeline was created to offer a simpler and more opinionated syntax for authoring Jenkins Pipeline.
  • Both are fundamentally the same Pipeline sub-system underneath. They are both durable implementations of “Pipeline as code.” They are both able to use steps built into Pipeline or provided by plugins.

 

Pipeline Example Syntax

Consider the following Pipeline which implements a basic three-stage continuous delivery pipeline.

The most fundamental part of a pipeline is “steps”, which tell Jenkins what to do and serve as a basic building block.

You should be able to construct a more complex example using Directives and Steps.

            pipeline {
	    agent any
	

	    stages {
	        stage('Build') {
	            steps {
	                echo 'Building...'
	            }
	        }
	        stage('Test') {
	            steps {
	                echo 'Testing...'
	            }
	        }
	        stage('Deploy') {
	            steps {
	                echo 'Deploying....'
	            }
	        }
	    }
	}

        

We will see this in details in next section when we create pipeline for UiPath project.

UiPath Jenkins Plugin

The UiPath Jenkins Plugin allows you to integrate RPA development and Software Testing with UiPath into Jenkins.

It provides build tasks to pack UiPath projects into nuget packages, deploy them to Orchestrator and run Test Sets on Orchestrator.

Installing and enabling the plugin

  1. You can install UiPath Plugin using the Plugin Manager screen.
  2. Once Plugin is Installed you can use Snippet Generator also to create snippets of code for practically all the steps available within a pipeline.

 

UiPath Jenkins Plugin

Using Global and Local Environment Variables

Jenkins Pipeline exposes environment variables via the global variable env, which is available from anywhere within a Jenkinsfile.

Environment variables are accessible from Groovy code as env.VARNAME or simply as VARNAME. You can write to such properties as well (only using the env. prefix).

Below are few common environment variables we will use inside our pipeline.

  1. BRANCH_NAME – Name of the branch being built.
  2. BUILD_NUMBER – The current build number, such as “12”
  3. JOB_NAME – Name of the project of this build.
  4. JENKINS_HOME – The absolute path of the directory assigned on the master node for Jenkins to store data.
  5. JOB_URL – Full URL of this job, like http://server:port/jenkins/job/foo/ (Jenkins URL must be set)

(The full list of environment variables accessible from within Jenkins Pipeline is documented at ${YOUR_JENKINS_URL}/pipeline-syntax/globals#env)

 

Note –

  1. The currentBuild variable, which is of type RunWrapper, may be used to refer to the currently running build to get information on current results, duration.
  2. You can also use a sequence of key-value pairs which will be defined as environment variables for all steps, or stage-specific steps, depending on where the environment directive is located within the Pipeline.

Handling Credentials/API Keys

Jenkins’ declarative Pipeline syntax has the credentials() helper method (used within the environment directive) which supports secret text, username and password, as well as secret file credentials.

You can create Credentials by Navigating to  Credentials Page and selecting the Store (Logical group to separate access).

For our example, we need to store basic username and password if using on-perm orchestrator or user APIKEY in case you are using cloud orchestrator.

Handling Credentials/API Keys

Supported Credentials Type:

  • Secret Text – Can be used to store API Keys
  • Secret File – Can be used to access location of the file.
  • Username and password – the environment variable specified will be set to username:password and two additional environment variables will be automatically defined: MYVARNAME_USR and MYVARNAME_PSW respectively.
  • SSH with Private Key – environment variable specified will be set to the location of the SSH key file

Handling Failure/Notification/Cleanup

Declarative Pipeline supports robust failure handling by default via its post section which allows declaring a number of different “post conditions” such as: always, unstable, success, failure, and changed.

Example Syntax.(You can do many steps here like sending email, approval, Slack Notification etc…)

            post 
		    {
		        changed
		        {
		            echo "Status has changed"
		        }
		        failure
		        {
		            echo "Status is failure"
		            //You can post your failure message here
		        }
		        success
		        {
		            echo "Status is success"
		            //You can post your failure message here and probably you wish to send email to notification
		        }
		        unstable
		        {
		            echo "Status is unstable"
		        }
		        aborted
		        {
		            echo "Status is aborted"
		            //Good to send Slack Notification when aborted
		        }
		        always {
	            script {
	                BUILD_USER = getBuildUser()
	            }
	            echo 'I will always say hello in the console.'
	            slackSend channel: '#slack-test-channel',
	                color: COLOR_MAP[currentBuild.currentResult],
	                message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} build ${env.BUILD_NUMBER} by ${BUILD_USER}\n More info at: ${env.BUILD_URL}"
	        }
	

		 }


        

Working Example (Using Jenkinsfile Declarative Pipeline)

So far so good, we have covered almost all the basic details we need to Build our UiPath Pipeline.

At this point of article, I assume you have.

  1. Jenkins Installed locally or On Network (for testing we installed it locally on the same machine where we have UiPath)
  2. You have your source code available in Git or any Version control system.
  3. You have required credentials for accessing the UiPath Orchestrator Instance (enterprise or cloud)

Let’s see our pipeline working – (We will do it in two steps)

Step 1 – Create New Item as “Multi-branch pipelines” using GitHub Source code.

  • Click New Item in the top left corner on the Jenkins dashboard.
  • Enter the name of your project in the Enter an item name field, scroll down, and select Multibranch Pipeline and click OK button.
Jenkins Multi-branch pipelines
  • Add a Branch Source (for example, GitHub) and enter the location of the repository.
  • Select the Add button to add credentials and click Jenkins. Enter the GitHub username, Password, ID, and Description
Multi Branch Pipelilines Git Hub Source Codes
  • You also need to configure the Build; you can select the Mode as by Jenkinsfile and Script Path as you wish to name it.
  • Jenkins automatically scans the designated repository and does some indexing for organization folders. You might need to configure the webhooks to communicate with our GitHub repository.
Multi Branch Pipelines Build Configuration

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Step 2- Create your initial Pipeline as a Jenkinsfile with build and test stages

You’re now ready to create the Pipeline that will automate building your UiPath Project in Jenkins.

  • Use your favourite text editor or IDE, open the existing Jenkinsfile at the root of your project or create new Jenkinsfile
  • Copy the following Declarative Pipeline code and paste it into your empty Jenkinsfile:
            pipeline {
	    agent any
	

	        // Environment Variables
	        environment {
	        MAJOR = '1'
	        MINOR = '0'
	        //Orchestrator Services
	        UIPATH_ORCH_URL = "https://cloud.uipath.com/"
	        UIPATH_ORCH_LOGICAL_NAME = "AIFabricDemo"
	        UIPATH_ORCH_TENANT_NAME = "UATdfds611009"
	        UIPATH_ORCH_FOLDER_NAME = "Shared"
	    }
	

	    stages {
	

	        // Printing Basic Information
	        stage('Preparing'){
	            steps {
	                echo "Jenkins Home ${env.JENKINS_HOME}"
	                echo "Jenkins URL ${env.JENKINS_URL}"
	                echo "Jenkins JOB Number ${env.BUILD_NUMBER}"
	                echo "Jenkins JOB Name ${env.JOB_NAME}"
	                echo "GitHub BranhName ${env.BRANCH_NAME}"
	                checkout scm
	

	            }
	        }
	

	         // Build Stages
	        stage('Build') {
	            steps {
	                echo "Building..with ${WORKSPACE}"
	                UiPathPack (
	                      outputPath: "Output\\${env.BUILD_NUMBER}",
	                      projectJsonPath: "project.json",
	                      version: [$class: 'ManualVersionEntry', version: "${MAJOR}.${MINOR}.${env.BUILD_NUMBER}"],
	                      useOrchestrator: false
	        )
	            }
	        }
	         // Test Stages
	        stage('Test') {
	            steps {
	                echo 'Testing..the workflow...'
	            }
	        }
	

	         // Deploy Stages
	        stage('Deploy to UAT') {
	            steps {
	                echo "Deploying ${BRANCH_NAME} to UAT "
	                UiPathDeploy (
	                packagePath: "Output\\${env.BUILD_NUMBER}",
	                orchestratorAddress: "${UIPATH_ORCH_URL}",
	                orchestratorTenant: "${UIPATH_ORCH_TENANT_NAME}",
	                folderName: "${UIPATH_ORCH_FOLDER_NAME}",
	                environments: 'DEV',
	                //credentials: [$class: 'UserPassAuthenticationEntry', credentialsId: 'APIUserKey']
	                credentials: Token(accountName: "${UIPATH_ORCH_LOGICAL_NAME}", credentialsId: 'APIUserKey'), 
	

	        )
	            }
	        }
	

	

	         // Deploy to Production Step
	        stage('Deploy to Production') {
	            steps {
	                echo 'Deploy to Production'
	                }
	            }
	    }
	

	    // Options
	    options {
	        // Timeout for pipeline
	        timeout(time:80, unit:'MINUTES')
	        skipDefaultCheckout()
	    }
	

	

	    // 
	    post {
	        success {
	            echo 'Deployment has been completed!'
	        }
	        failure {
	          echo "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.JOB_DISPLAY_URL})"
	        }
	        always {
	            /* Clean workspace if success */
	            cleanWs()
	        }
	    }
	

	}


        
  • Save your edited Jenkinsfile and commit it the Git Repo. That’s all you need to do for now.

Lets quickly run the Build to see the results.

If everything goes well you should be able to see the published package inside your orchestrator instance.

 

Multi Branch Pipelines Build Success Result

Running you Build Pipeline

  1. Go back to the repository and change to the Branch and Update any of the files. In our example, we update the README.md file.
  2. You will see that the Jenkins job will trigger automatically. (it scans the repo and create Build Queues)
  3. You can also run the “pipeline” by manually scanning the Repository.
Multi Branch Pipelines Build Status
Stage Wise Build status
Multi Branch Pipelines Build Status Console Logs
You can see the console logs by navigating to Build history.
Multi Branch Pipelines Build Status Console Logs Output

UiPath, Jenkins CICD Pipeline - Part 1 [By Anupam Krishnamurthy]

UiPath, Jenkins CICD Pipeline - Part 2 [By Anupam Krishnamurthy ]

How do I configure a user account to have ‘logon as a service’ permissions?

When installing a service to run under a domain user account, the account must have the right to logon as a service on the local.

Perform the following to edit the Local Security Policy of the computer you want to define the ‘logon as a service’ permission:

  • Logon to the computer with administrative privileges.
  • Open the ‘Administrative Tools’ and open the ‘Local Security Policy’
  • Expand ‘Local Policy’ and click on ‘User Rights Assignment’
  • In the right pane, right-click ‘Log on as a service’ and select properties.
  • Click on the ‘Add User or Group…’ button to add the new user.
  • In the ‘Select Users or Groups’ dialogue, find the user you wish to enter and click ‘OK’
  • Click ‘OK’ in the ‘Log on as a service Properties’ to save changes.

Refer Jenkins installation setup

How do I configure Orchestrator API Keys?

  1. The Tenants page enables you to access API specific information for each of your existing Orchestrator services (if you have the Organization Owner or Organization Administrator role).
  2. Navigate to Admin > Tenants. The Tenants page is displayed with a list of all existing tenants.
  3. Expand the desired tenant to display the available services.
  4. Click API Access () for the corresponding Orchestrator service. The API Access window is displayed with the following service-specific information:
    • User Key – allows you to generate unique login keys to be used with APIs or with 3rd party applications in order to log in and perform actions on your behalf. This was previously known as your refresh token.
    • Account Logical Name – your unique site URL, (for example cloud.uipath.com/yoursiteURL). Read more about it here.
    • Tenant Name – the tenant’s display name.
    • Client Id – specific to the Orchestrator application itself, it is the same for all users and Orchestrator services on a specific platform. For example, all the Orchestrator services on cloud.uipath.com have the same Client Id value.