Jenkins
Check for the latest updates and install wget
sudo apt-get update && sudo apt install wget
Configuring limits
Edit the file limit.conf
sudo vi /etc/security/limits.conf
Adding content:
jenkins soft core unlimited
jenkins hard hard unlimited
jenkins soft fsize unlimited
jenkins soft fsize unlimited
jenkins soft nofile 4096
jenkins hard nofile 8192
jenkins soft nproc 30654
jenkins hard nproc 30654
Configure the firewall
sudo apt-get install ufw
sudo ufw allow OpenSSH
sudo ufw allow 8080
sudo ufw enable
Check ufw’s status to confirm the new rules:
sudo ufw status
Checking java
java --version
If java is missing, install
sudo apt install openjdk-11-jre-headless
Java 11 Docker installation instructions are included in “Downloading and running Jenkins in Docker”. Alternatively, the jenkins/jenkins:jdk17 Docker image allows you to run the Jenkins controller on Java 17.
All other Java versions are not supported. The Jenkins project performs a full test flow with the following JDK/JREs:
OpenJDK JDK / JRE 11 - 64 bits
OpenJDK JDK / JRE 17 - 64 bits
Installing Jenkins
The version of Jenkins included with the default Ubuntu packages is often behind the latest available version from the project itself. To ensure you have the latest fixes and features, use the project-maintained packages to install Jenkins.
First, add the repository key to your system:
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key |sudo gpg --dearmor -o /usr/share/keyrings/jenkins.gpg
The gpg --dearmor
command is used to convert the key into a format that apt
recognizes.
Next, let’s append the Debian package repository address to the server’s sources.list
:
sudo sh -c 'echo deb [signed-by=/usr/share/keyrings/jenkins.gpg] http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
The [signed-by=/usr/share/keyrings/jenkins.gpg]
portion of the line ensures that apt
will verify files in the repository using the GPG key that you just downloaded.
After both commands have been entered, run apt update so that apt will use the new repository.
sudo apt update
Finally, install Jenkins and its dependencies:
sudo apt install jenkins
now that Jenkins is installed, start it by using systemctl
:
sudo systemctl start jenkins.service
Since systemctl
doesn’t display status output, we’ll use the status command to verify that Jenkins started successfully:
sudo systemctl status jenkins
auto run after restart
systemctl enable jenkins
Configure additional Java parameters:
Garbage collection options
sudo vi /lib/systemd/system/jenkins.service
"JAVA_OPTS=-Djava.awt.headless=true -XX:+AlwaysPreTouch -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/jenkins/log -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:+DisableExplicitGC -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xlog:gc=info,gc+heap=debug,gc+ref*=debug,gc+ergo*=trace,gc+age*=trace:file=/var/lib/jenkins/gc.log:utctime,pid,level,tags:filecount=2,filesize=100M -Xmx512m -Xms512m"
Note: -Xmx512m
-Xms512m
set depending on the available memory in the virtual machine
Setting Up Jenkins
To set up your installation, visit Jenkins on its default port, 8080
, using your server domain name or IP address: http://your_server_ip_or_domain:8080
You should receive the Unlock Jenkins screen, which displays the location of the initial password:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
The next screen presents the option of installing suggested plugins or selecting specific plugins
Slave and Master
Agent SSH Jenkins
java -- version
sudo apt install openjdk-11-jre-headless
useradd -m -s /bin/bash jenkins
passwd jenkins
openssh installed or not
apt list -installed | grep openssh-server
sudo service ssh status
install openssh-server
sudo apt install openssh-server
install jenkins on docker-compose.yml
sudo su
vi docker-compose.yml
# docker-compose.yml
version: '3.3'
services:
jenkins:
image: jenkins/jenkins:lts-jdk11
restart: always
privileged: true
user: root
ports:
- 8080:8080
- 50000:50000
container_name: jenkins
volumes:
- /home/${myname}/jenkins_compose/jenkins_configuration:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
docker-compose up -d
cd /home/root/jenkins_compose/jenkins_configuration
cd secret
cat initialAdminPassword
SSH-Key Generate
ssh-keygen -t rsa -f jenkins_slave -m PEM
Execute the command and copy the contents of the file:
cat jenkins_slave
Open the jenkins web interface, go to the Manager Jenkins -> Manager Credentials
Go to the global domain
Click Add Credentials
, fill in as in the screenshots below, enter the previously copied private key in the key field
- Kind
-
SSH Username with private key
-
- id
team01-agent-ssh
- Username
jenkins
and push button “create”
Copy private key to slave machine agent
ssh-copy-id -i jenkins_slave.pub jenkins@vs02slave
Go to the Jenkins web interface - Manage Jenkins -> Manage Node and Cloud
Click New Node, enter name agent, and - [x] Permanent Agent box
Create and fill all:
name node: team01-agent
discription: agent for team01
number of executors: 1
remote root directory: /home/jenkins
labals: linux
Usage:
- ‘Only build jobs with label expressions matching this node’
launch method: Launch agents via SSH
host: `(number_of_slave_ip_machine) or dns host name of slave'
Credentials: jenkins
Host Key Verification Strategy: Non verifying Verification Strategy
Save
and We return to Manage Node -> select our agent
push Relaunch agent
and see log if all ok
pipline{
agent
}
Jenkins Plugins Installation
- Web UI
- CLI
- /var/lib/Jenkins/plugins
Jenkins Plugin. Most Useful
- Rebuilder
- Config File Provider
- Ansi Color
- Active Choice
Open the Jenkins web interface and go to Manage Jenkins-> Manage Plugins
In the Available list, look for plugins, select them and click “Download now and install after restart”
It is important to remember that restarting Jenkins running in a production environment is not recommended during working hours, although Jenkins waits for all tasks to finish before starting and only then restarts the kernel. Still, it is better to postpone such work for non-working hours. Or try to use the option “Install without restart” You also need to remember that for such an installation of Jenkins plugins, the master must have access to the internet. If there is no direct access, you can use the proxy settings, for this you need to go to the Advanced tab
Global Tool Configurations
- Maven
- JDK
- Cradle
- SonarQube
- Allure
- Etc
Add maven and npm to Global Tool Configuration
Consider the example of installing maven, for this we go to Manage Jenkins-> Tools
Add Maven
Name: maven-3.9.4
Version:
- [x] 3.9.4
apply and save
Jenkins Credentials ID
best practices
Jenkins Secret Password Decrypt
cat credentials.xml
copy past password
println(hudson.util.Secret.decrypt("{passwordcopypast}"))
Authentification
- Jenkins OWN database
- LDAP
- Unix User/Group Database
Create New item and Manage Roles
Opening the Jenkins web interface
To do this, click New Item
To get started, install the plugin Role-based Authorization Strategy
Go to Manage Jenkins -> Configure Security and activate Role-Base Strategy for Authorization
Security Realm:
-
Jenkin’s own user database
-
Role-Based Strategy
Save!
Go to Manage Jenkins -> Manage and Assign Roles -> Manage Roles
Role to add: QA
Pattern:
qa-.*
Deployment
Frestyle Jobs
one of the most popular configuration happens in web ui
Folder
- Common Namespace
- Shared Libraries
- Separate rights
Multibranch Pipeline
Pipeline
Groovy DSL to describe tasks:
- Stored in SCM ( Jenkinsfile)
- Defined in task settings
node('worker01') {
stage('Source') {
git 'http://github.com/silabeer/example-project'
sh ‘mvn clean install’
}
}
pipeline features
- Independence from agent or worker directories
- Parallelization
- Resist from Master restart
- Resist from network break
Building in Jenkins
Pipeline always runs on master
Groovy DSL
Scripted:
node {
stage('Hello world') {
sh 'echo Hello World'
}
}
Scripted pipline:
Plus:
- Less number of sections and specifications
- Ability to use more procedural code
- More flexibility for custom operations
- Ability to model more complex processes Minus:
- Needs more programming
- Far from the traditional Jenkins model
- Potentially more complicated
Declarative:
pipeline {
agent any
stages {
stage('Hello World') {
steps {
sh 'echo Hello World'
}
}
}
}
Declarative Pipeline: Plus:
- More structured
- More readable
- Can be generated through Blue Ocean
- Better syntax checking
- Improved consistency Minus:
- Less support for iterative logic
- More stiffer construction
Diagram of Declarative Pipeline sections
Snippet Generator
Environment Setup
VS Code:
- Jenkins Jack
- Jenkins Pipeline Linter
- Jenkins Runner
- Jenkins Doc
hostname test
pipeline {
agent {
label "linux"
}
stages {
stage ("test agent") {
steps {
sh 'hostname'
}
}
}
}
maven download and test version maven
pipeline {
agent {
label "linux"
}
tools {
maven "maven-3.9.4"
}
stages {
stage('test marven') {
steps {
sh "mvn --version"
}
}
}
}
hello word stages
pipeline {
agent {
label "linux"
}
stages {
stage('hello') {
steps {
sh 'echo "Hello World"'
}
}
stage('hello2') {
steps {
sh 'echo "Hello World2"'
}
}
stage('hello3') {
steps {
sh 'echo "Hello World3"'
}
}
}
}
first.Jenkinsfile
pipeline {
agent {
label "linux"
}
tools {
maven "maven-3.9.4"
}
stages {
stage('checkout') {
steps {
git credentialsId: 'team1', url: 'https://github.com/nayaks/spring-boot-rest-example.git'
}
}
stage('build') {
steps {
sh "mvn clean install -Dmaven.test.skip"
}
}
}
}
git branch: ‘main’, credentialsId: ‘s043218-dev-gitlab’, url: ‘https://gitlab.slurm.io/jenkins/spring-boot-rest-example.git'
mvn clean install -Dmaven.test.skip.
Tests are run with mvn test
pipeline {
<pipeline code>
}
The trigger section is used to define the pipeline launch schedule. It accepts 4 values: cron
, upstream
, githubPush
, pollSCM
cron - runs a task according to a given schedule, and pollSCM launches a check for source code updates, if a change is detected, it starts the execution of the pipeline
Example:
Launch of the conveyor in a quarter of an hour
trigger { *cron(15 * * * ) }
pipeline {
agent any
triggers {
cron('H */4 * * 1-5')
}
Scan for SCM changes at 20-minute intervals
trigger { pollSCM(/20 * * * ) }
upstream - starts a task based on the condition of another task being completed Example:
trigger { upstream(upstreamProjects: 'trigger-job', threshold:hudson.model.Result.SUCCESS) }
will start execution after successful completion of the trigger-job
githubPush - starts the pipeline in case of receiving a webhook from github
For additional pipeline options, use the options section
buildDiscarder - saves a given number of artifacts and console logs for a job
Example:
options { buildDiscarder(logRotator(numToKeepStr: '20')) }
leaves a history of the last 20 builds
disableConcurrentBuilds - disables parallel execution of the same pipeline
Example:
options { disableConcurrentBuilds() }
retry - if the pipeline fails, it will be restarted the specified number of times
Example:
options { retry(2) }
in case of failure, restart the pipeline
timeout - sets the timeout value for the pipeline, if the execution time exceeds timeout, the pipeline will exit
Example:
options { timeout (time: 15, unit: 'MINUTES') }
sets timeout to 15 minutes
timestamps - adds a timestamp to the console log
Example:
options { timestamps() }
The environment directive allows you to specify the names and values of environment variables that will be available within the pipeline. Defining a variable at the top of the pipeline will make the variable available in all parts of the pipeline
environment {
TEST_VAR = "test"
}
in the pipeline itself can be used as follows:
stage('test') {
steps {
echo "${TEST_VAR}"
}
hostname test
pipeline {
agent {
label "linux"
}
stages {
stage ("test agent") {
steps {
sh 'hostname'
}
}
}
}
maven download and test version maven
pipeline {
agent {
label "linux"
}
tools {
maven "maven-3.9.4"
}
stages {
stage('test marven') {
steps {
sh "mvn --version"
}
}
}
}
Environment
pipeline {
agent {
label "linux"
}
stages {
stage('test') {
steps {
sh "env | sort"
}
}
}
}
Global environment exemple:
pipeline {
agent {
label "linux"
}
environment {
MY_GLOBAL_VAR = 'myEnv'
}
stages {
stage('test') {
steps {
sh 'echo $MY_GLOBAL_VAR'
sh "env | sort"
}
}
}
}
local environment exemple :
only stage2 not stage3
pipeline {
agent {
label "linux"
}
environment {
MY_GLOBAL_VAR = 'globalVar'
}
stages {
stage('stage1') {
steps {
sh 'echo $MY_GLOBAL_VAR'
sh "env | sort"
}
}
stage('stage2') {
environment {
MY_STAGE_VAR = 'stageVar'
}
steps {
sh 'echo $MY_STAGE_VAR'
sh "env | sort"
}
}
stage('stage3') {
steps {
sh 'echo $MY_STAGE_VAR'
sh "env | sort"
}
}
}
}
pipeline {
agent {
label "linux"
}
environment {
MY_GLOBAL_VAR = 'globalVar'
MY_RANDOM_VAR = sh(script: 'openssl rand -base64 32', returnStdout: true)
MY_SECRET_VAR = credentials('secret-username')
}
stages {
stage('stage1') {
steps {
sh 'echo $MY_GLOBAL_VAR'
sh 'env | sort'
}
}
stage('stage2') {
environment {
MY_STAGE_VAR = 'stageVar'
}
steps {
sh 'echo $MY_STAGE_VAR'
sh 'env | sort'
}
}
stage('stage3') {
steps {
sh 'echo $MY_STAGE_VAR'
sh 'env | sort'
}
}
stage('stage4') {
steps {
sh 'echo $MY_STAGE_VAR'
sh 'echo $MY_SECRET_TEXT'
sh 'env | sort'
}
}
}
}
only change in 1 stage
pipeline {
agent {
label "linux"
}
environment {
MY_GLOBAL_VAR = 'globalVar'
MY_RANDOM_VAR = sh(script: 'openssl rand -base64 32', returnStdout: true)
MY_SECRET_VAR = credentials('secret-username')
}
stages {
stage('stage1') {
steps {
sh 'echo $MY_GLOBAL_VAR'
sh 'env | sort'
}
}
stage('override variables') {
steps {
script {
env.MY_GLOBAL_VAR = "IT DOES WORK"
println '=====override====='
println "MY_GLOBAL_VAR"
}
echo "My_GLOBAL_VAR = ${env.MY_GLOBAL_VAR}"
withEnv(["MY_GLOBAL_VAR=localVar"]) {
echo "MY_GLOBAL_VAR = ${env.MY_GLOBAL_VAR}"
}
withEnv(["BUILD_NUMBER=1"]) {
echo "BUILD_NUMBER = ${env.BUILD_NUMBER}"
}
}
}
stage('stage2') {
environment {
MY_STAGE_VAR = 'stageVar'
}
steps {
sh 'echo $MY_STAGE_VAR'
sh 'env | sort'
}
}
stage('stage3') {
steps {
sh 'echo $MY_STAGE_VAR'
sh 'env | sort'
}
}
stage('stage4') {
steps {
sh 'echo $MY_STAGE_VAR'
sh 'echo $MY_SECRET_TEXT'
sh 'env | sort'
}
}
}
}
def myTestVar before pipeline
pipeline {
agent {
label "linux"
}
environment {
MY_GLOBAL_VAR = 'globalVar'
MY_RANDOM_VAR = sh(script: 'openssl rand -base64 19', returnStdout: true)
MY_SECRET_VAR = credentials('secret-username')
}
stages {
stage('stage1') {
steps {
sh 'echo $MY_GLOBAL_VAR'
sh "env | sort"
}
}
stage('override variables') {
steps {
script {
def myTestVar = "myTestVar"
println "myTestVar"
}
}
}
stage('stage2') {
steps {
script{
println = "myTestVar"
}
sh 'echo $MY_GLOBAL_VAR'
sh 'env | sort'
}
}
}
}
CatchError
catchError - ignore error step and go to stage 2
’exit 1’ - its exit from stage
but pipeline finish with status FAILURE
pipeline {
agent {
label "linux"
}
stages {
stage('Hello') {
steps {
catchError {
sh 'exit 1'
}
}
}
stage('stage2') {
steps {
sh "echo stage2"
}
}
}
}
if you want status UNSTABLE you can change in catch error command
catchError(message:'Skip because unstable',buildResult:'UNSTABLE',stageResult:'UNSTABLE')
retry
- its retry code in { }
pipeline {
agent {
label "linux"
}
stages {
stage('Hello') {
steps {
catchError(message:'Skip because unstable',buildResult:'UNSTABLE',stageResult:'UNSTABLE') {
retry(3) {
sh 'exit 1'
}
}
}
}
stage('stage2') {
steps {
sh "echo stage2"
}
}
}
}
Script pipeline
pipeline {
agent {
label "linux"
}
stages {
stage('Hello') {
steps {
script {
try {
retry(2) {
sh 'exit 1'
}
}
catch (err) {
currentBuild.result = 'Unstable'
}
}
}
}
stage('stage2') {
steps {
sh "echo stage2"
}
}
}
}
WaitUntil
WaitUntil = wait to ..
fileExists = file be
pipeline {
agent {
label "linux"
}
stages {
stage('stage1') {
steps {
sh 'touch 1'
timeout(5) {
waitUntil {
fileExists 'myFile.yaml'
}
}
}
}
}
}
Lockable Resource database
its plugin need install (lockable Resource) after
Configure System => System => Lockable Resources Manager
Resource:
Name: SCHEMA_1
Labels: database
SAVE
pipeline {
agent {
label "linux"
}
stages {
stage('stage1') {
steps {
lock(label: 'database', variable: 'LOCKED RESOURCE', quantity: 1) {
echo env.LOCKED_RESOURCE
sh 'echo Hello World'
sleep 60
}
}
}
}
}
Groovy Scripts
-
pipeline done failed its ok
-
- ansi color plugin
pipeline {
agent {
label "linux"
}
options {
ansiColor('xterm')
}
stages {
stage('stage1') {
steps {
script {
getFile().each { p ->
sh "mkdir -p $p.folder"
sh "touch $p.folder/$p.name"
}
println getProjectName()
error("error message")
}
}
}
}
}
def getProjectName() {
return 'JenkinsPipeline'
}
def List getFile() {
return [
[name: 'file01', folder: 'folder01'],
[name: 'file02', folder: 'folder02'],
]
}
def loadColors() {
CEND = '\033[0m'
CVIOLENTBG2 = '\033[91m'
}
def error(String message) {
loadColors()
sh """
set +x; echo "${CVIOLENTBG2} $message ${CEND}"
"""
}
From Pipeline from file hello.groovy
2 files :
Jenkinsfile
def code
pipeline {
agent {
label "linux"
}
stages {
stage('Stage1') {
steps {
sh 'echo "stage1"'
script {
code = load 'scripts/hello.groovy'
code.example1()
}
}
}
stage('stage2') {
steps {
sh 'echo "stage2"'
script {
code.example2()
}
}
}
}
}
hello.groovy
def example1() {
printnl 'Hello from example1'
}
def example2() {
printnl 'Hello from example2'
}
return this
Description
getAllIteams()?.
findAll { !it.getDescription() }?.
each {
println "'${it.fullName}' doesn't explain it does..."
}
println''
Space in name
getAllIteams()?.
findAll { !it.name.contains(' ') }?.
each {
println "'${it.fullName}' contains spaces!"
}
println''
Log rotation
getAllItems(Job.class)?.
each {
found = true
if (it.getBuildDiscarder() )
found = it.getBuildDiscarder().getArtifactDaysToKeep() < 0 &&
it.getBuildDiscarder().getArtifactNumToKeep() < 0 &&
it.getBuildDiscarder().getArtifactDaysToKeep() < 0 &&
it.getBuildDiscarder().getDaysToKeep() < 0 &&
it.getBuildDiscarder().getNumToKeep() < 0
if (found)
println"'${it.fullName}' doesn't have any log rotator configuration"
}
println ''
Parameters in Jenkins
To add parameters to the Job, you must check the box “This project is parameterised”:
To parameterize the pipeline in jenkins, the parameter section is used. The following types of parameters are available in the box:
- Boolean Parameter - defines boolean parameters. Can take values true or false. You can also set a default value for a parameter.
booleanParam (name: «DryRun», defaultValue: true, description: «test run»)
- String Parameter - defines a single line parameter. Supports removing spaces on both sides of the entered value.
string (name: «version», defaultValue: «r48», trim: false, description: «enter verision component»)
- Multi-line String Parameter - define a multiline parameter.
text (name: «releaseNotes», defaultValue: «none», description: «Оdescription of changes in the release»)
- Password - allows you to define a password entry. Password details will not appear on startup
Job
and inconsole log
.
password (name: «password», defaultValue: «changeme», description: «enter password»)
- Choice Parameter - allows you to select multiple options from a list of previously preset options.
choice (name: «env», choices: [«PROD», «DEV», «UAT»], description: «choose an environment to install the release»)
How to declare parameters in Jenkinsfile
pipeline {
agent any
parameters {
booleanParam(name: "dryrun", defaultValue: true, description: "test run")
string(name: "version", defaultValue: "r48", trim: true, description: "Entry verion of component")
text(name: "releaseNotes", defaultValue: "Добавлены новые feature", description: "Description of changes in the release")
password(name: "password", defaultValue: "changeme", description: "Entry password")
choice(name: "env", choices: ["PROD", "DEV", "UAT"], description: "Sample multi-choice parameter")
}
stages {
stage('DryRun') {
when {
expression { params.dryrun }
}
steps {
echo "THIS IS DRYRUN!"
}
}
stage("Build") {
steps {
echo "Build stage."
echo "Hello $params.version"
}
}
stage("Test") {
steps {
echo "Test stage."
}
}
stage("Release") {
steps {
echo "Defined release notes $params.releaseNotes"
echo "Starting release on $params.env"
}
}
}
}
Active Choice Parameter
The Active Choice Parameter is not added by default. To use it, you first need to install the Active Choices plugin.
Active Choices is used to parameterize a Jenkins Job and to create dynamic and interactive options. Active Choices options can be dynamically updated and displayed in the form of list fields, flags, switches, or user interface widgets with HTML..
3 additional options in the parameters section:
-
Active Choices Parameter - allows to use Groovy script or Scriplet(plugin), to identify, whether the input will be calculated or it’s already predetermined, and return results depending on the scripts being executed.
-
Active Choices Reactive Parameter - like Active Choice Parameter. It will allow you to use Groovy or Scriplet, and its value varies depending on the value of the selected dependent parameter.
-
Active Choices Reactive Reference Parameter contains parameters Active Choice Parameter + Active Choice Reactive Parameter, also adds new options.For example, HTML-widget, labeled or numbered lists, and input fields.
Let’s move to practice: case study of using Active Choice Parameter
et’s imagine that you have a task to make a Job that will allow development or L2 support to install a service of a certain version in the right environment. It seems that everything should be automated, but in practice there is a situation when a developer or QA engineer wants to test his version of a microservice on a certain environment. This could be done using regular string parameters, but let’s simplify the task and provide a more user-friendly interface.
Let’s start by adding component selection using the gitlab api, write a simple groovy script to get a list of projects, and then create a Jenkinsfile and add our parameter definition to it:
properties([
parameters([
[$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select a choice',
filterLength: 1,
filterable: false,
name: 'component',
script: [$class: 'GroovyScript',
fallbackScript: [classpath: [], sandbox: false, script: 'return ["Could not get component"]'],
script: [classpath: [], sandbox: false,
script: """
import groovy.json.JsonSlurperClassic
def list = []
def connection = new URL("https://run.mocky.io/v3/e406ee99-be79-4d50-818f-b186dad7f4f4")
.openConnection() as HttpURLConnection
connection.setRequestProperty('Accept', 'application/json')
def json = connection.inputStream.text
data = new JsonSlurperClassic().parseText(json)
data.each { component ->
list += component.name
}
return list
"""
]]]])
])
pipeline {
agent any
stages {
stage("Component Name") {
steps {
sh "echo Selected component ${params.component}"
}
}
}
}
Don’t forget that new scripts need to be validated
Now let’s move on to creating Active Choices Reactive Parameter. Depending on the selected component, we will be shown all versions of the component in the artifactor.
Let’s create a simple groovy script and add a description to Jenkinsfile:
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select Version',
filterLength: 1,
filterable: true,
name: 'version',
referencedParameters: 'component',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script:
'return[\'Could not get version\']'
],
script: [
classpath: [],
sandbox: false,
script:
"""
import groovy.json.JsonSlurperClassic
def list = []
def connection = new URL("https://run.mocky.io/v3/c782ae33-98a2-4994-acc4-14c0b5cc7655")
.openConnection() as HttpURLConnection
connection.setRequestProperty('Accept', 'application/json')
def json = connection.inputStream.text
data = new JsonSlurperClassic().parseText(json)
data.data.each { it ->
if (it.component == component ) {
list += it.version
}
}
return list
"""
]
]
]
An important change is the referencedParameters
option. In it we specify the parameter on which the script execution depends. Run our Job, select the component and version and look at the result:
integration with Gitlab
To get started, install the Gitlab
plugin and Gitlab branch
After installation, need restart Jenkins
Go to Gitlab and go to project Access Tokens => Add New Token
select all scopes and copy past personal access token (do not copy stars)
Go to => Manage Jenkins => Credentials => Global => Add Credentials
past personal access token to api token and create! do not copy stars
Dashboard => Manage Jenkins => System
test connection
Create for user token
Go to Gitlab -> Settings -> Webhook
!!! Webhook not work from local machine !!! i used ngrok
Webhook need for synchronization change jenkins branch
https://user:[email protected]/project/nameofproject.git
Let’s go to New Item => Multibranch pipeline
Click Add source
Select Git
Enter your Repository URL (e.g.: [email protected]:group/repo_name.git)
save
after it jenkins scan all branch Jenkinsfile
on Gitlab
for examlpe:
pipeline {
agent any
tools {
maven 'maven-3.9.4'
}
stages {
stage('Checkout') {
steps {
script {
checkout scm
}
}
}
stage('Build') {
steps {
sh "env | sort"
sh 'mvn clean install'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage(Only 'MR') {
when {
branch 'MR-*'
}
steps {
sh "env | sort"
}
}
}
}
MR = Merge Request
\\
pipeline {
agent any
post {
failure {
updateGitlabCommitStatus name: 'build', state: 'failed'
}
success {
updateGitlabCommitStatus name: 'build', state: 'success'
}
aborted {
updateGitlabCommitStatus name: 'build', state: 'canceled'
}
}
options {
gitLabConnection('your-gitlab-connection-name')
}
triggers {
gitlab(triggerOnPush: true, triggerOnMergeRequest: true, branchFilterType: 'All')
}
stages {
stage("build") {
steps {
updateGitlabCommitStatus name: 'build', state: 'running'
echo "hello world"
}
}
}
[...]
}
gitLabConnection - allows ours within a single Jenkins , work with multiple gitlab installations, by specifying the right one for each pipeline
triggers - Added an option to the triggers section: gitlab - allows you to configure a trigger by event from gitlab
gitlabCommitStatus - allows you to notify gitlab of build steps
updateGitlabCommitStatus - allow you to notify giltab of status pipeline \\
Maven
Install plugin pipeline maven integration
After installation, we have an additional snippet inside steps
Need Create new account in jenkins name_of_user-gitlab-user
if you get his error need install git on agents
ERROR: Error cloning remote repo 'origin'
hudson.plugins.git.GitException: Could not init /home/jenkins/workspace/maven
or path in gloobal jenkins => tools => git /usr/bin/git
withMaven - any mvn command executed inside this block will be processed by the withMaven wrapper
maven - version of maven declared in Tools
pipeline {
agent {
label 'linux'
}
stages {
stage('checkout') {
steps {
git branch: 'master', credentialsId: '15388941-gitlab-user', url: 'https://gitlab.com/DanPoznanski/spring-boot-rest-example.git'
}
}
stage('build') {
steps {
withMaven(maven: 'maven-3.9.4')
{
sh "mvn clean install -DskipTests=true"
}
}
}
stage('test') {
steps {
withMaven(maven: 'maven-3.9.4') {
sh "mvn test"
}
}
}
}
}
Create XML Manage Files
когда нету доступа к интернету.. и хранить секреты..
its plugin
when there is no access to the Internet.. and you nedd keep secrets..
Manage Jenkins => Add new Config
hot to integrate to pipeline xml file
mavenSettingsConfig - id settings.xml file from config file provider
*** -s ${env.MVN_SETTINGS} *** - its take from tmp settings xml /home/jenkins/workspace/maven@tmp/withMaven86ec651/setting.xml
mavenOpts - additional mvn options such as XmX, XmS, proxy settings and others
*** ‘-Xmx1G’ *** = 1G RAM MEMORY
mavenLocalRepo - path to the local repository
pipeline {
agent {
label 'linux'
}
environment {
ADDITIONAL_MVN_OPTS = '-Xmx1G'
}
stages {
stage('checkout') {
steps {
git branch: 'master', credentialsId: '15388941-gitlab-user', url: 'https://gitlab.com/DanPoznanski/spring-boot-rest-example.git'
}
}
stage('build') {
steps {
withMaven(maven: 'maven-3.9.4', mavenSettingsConfig: 'my-project', mavenOpts: '$ADDITIONAL_MVN_OPTS') {
sh "env | sort"
sh "mvn clean install -s ${env.MVN_SETTINGS} -DskipTests=true"
}
}
}
stage('test') {
steps {
withMaven(maven: 'maven-3.9.4', mavenSettingsConfig: 'my-project', mavenOpts: '$ADDITIONAL_MVN_OPTS') {
sh "mvn test -s ${env.MVN_SETTINGS}"
}
}
}
}
}
Also withMaven offers the ability to work with ‘.jar’ files obtained as a result of pipeline execution and test results.
artifactsPublisher(disabled: true)
- publish jar files
pipeline {
agent {
label "linux"
}
environment {
ADDITIONAL_MVN_OPS = '-Xmx1G'
}
stages {
stage('checkout') {
steps {
git branch: 'master', credentialsId: 'user15388941-gitlab-token', url: 'https://gitlab.com/DanPoznanski/spring-boot-rest-example.git'
}
}
stage('build') {
steps {
withMaven(maven: '3.9.4',mavenSettingConfig: 'my-project' mavenOpts: '${ADDITIONAL_MVN_OPS}',options: [artifactsPublisher(disabled: true)])
{
sh "evn | sort"
sh "mvn clean install -s ${env.MVN_SETTINGS} -DskipTests=true"
}
}
}
stage('test') {
steps {
withMaven(maven: '3.8.6' mavenOpts: '${ADDITIONAL_MVN_OPS}',options: [artifactsPublisher(disabled: true)]) {
sh "mvn test -s ${env.MVN_SETTINGS}"
}
}
}
}
}
Sonarqube
Install plugin sonarqube scanner
need server sonarqube
plugin in stock extension email notifaction
pipeline {
agent {
label:linux
}
parameters {
choice(name: "env", choices: ["PROD", "DEV", "AUT"], description: "choice env")
}
stages {
stage(maintenance 'PROD') {
when {
expression {
params.env = 'PROD'
}
}
steps {
sh 'sleep 10'
}
}
}
post {
always {
emailext body: 'SUCCESS', subject: 'Maintenance finished', to '[email protected]'
}
}
}
Nexus
Install plugin nexus artifact upload
pupeline utility steps
pipeline {
agent {
label 'linux'
}
environment {
ADDITIONAL_MVN_OPTS = '-Xmx256m -Xx:+UseConcMarkSweepGC'
NEXUS_VERSION = 'nexus3'
NEXUS_PROTOCOL = 'http'
NEXUS_URL = "192.168.1.333:8081"
NEXUS_REPOSITORY = 'maven-local'
NEXUS_CREDENTIALID = 'dev-nexus'
}
stages {
stage('checkout') {
steps {
git branch: 'main', url: 'https://github.com./silabeer/spring-boot-example.git'
}
}
stage('build') {
steps {
withMaven(maven: '3.8.6',mavenSettingConfig: 'my-project' mavenOpts: '${ADDITIONAL_MVN_OPS}',options: [artifactsPublisher(disabled: true)])
{
sh "evn | sort"
sh "mvn clean install -s ${env.MVN_SETTINGS} -DskipTests=true"
}
}
}
stage('test') {
steps {
withMaven(maven: '3.8.6' mavenOpts: '${ADDITIONAL_MVN_OPS}',options: [artifactsPublisher(disabled: true)]) {
sh "mvn test -s ${env.MVN_SETTINGS}"
}
}
}
}
}
}
pipeline {
agent {
label "master"
}
tools {
maven "Maven"
}
environment {
NEXUS_VERSION = "nexus3"
NEXUS_PROTOCOL = "http"
NEXUS_URL = "you-ip-addr-here:8081"
NEXUS_REPOSITORY = "maven-nexus-repo"
NEXUS_CREDENTIAL_ID = "nexus-user-credentials"
}
stages {
stage("Clone code from VCS") {
steps {
script {
git 'https://github.com/javaee/cargotracker.git';
}
}
}
stage("Maven Build") {
steps {
script {
sh "mvn package -DskipTests=true"
}
}
}
stage("Publish to Nexus Repository Manager") {
steps {
script {
pom = readMavenPom file: "pom.xml";
filesByGlob = findFiles(glob: "target/*.${pom.packaging}");
echo "${filesByGlob[0].name} ${filesByGlob[0].path} ${filesByGlob[0].directory} ${filesByGlob[0].length} ${filesByGlob[0].lastModified}"
artifactPath = filesByGlob[0].path;
artifactExists = fileExists artifactPath;
if(artifactExists) {
echo "*** File: ${artifactPath}, group: ${pom.groupId}, packaging: ${pom.packaging}, version ${pom.version}";
nexusArtifactUploader(
nexusVersion: NEXUS_VERSION,
protocol: NEXUS_PROTOCOL,
nexusUrl: NEXUS_URL,
groupId: pom.groupId,
version: pom.version,
repository: NEXUS_REPOSITORY,
credentialsId: NEXUS_CREDENTIAL_ID,
artifacts: [
[artifactId: pom.artifactId,
classifier: '',
file: artifactPath,
type: pom.packaging],
[artifactId: pom.artifactId,
classifier: '',
file: "pom.xml",
type: "pom"]
]
);
} else {
error "*** File: ${artifactPath}, could not be found";
}
}
}
}
}
}
Jenkins Template Engine
Plugin need install Tempating Engine
Directory structure
Manage Jenkins -> System -> Jenkins Template Engine
Library Sources
Add From SCM
SCM
-> Git
Base Directory
-> your folder in gitlab
Credentials
-> Gitlab-user-token
after New Item -> Pipeline
copy past Jenkinsfile and Pipeline Configuration from gitlab
Jenkins Shared Library
Directory structure
(root)
+- src # Groovy source files
| +- org
| +- foo
| +- Bar.groovy # for org.foo.Bar class
+- vars
| +- foo.groovy # for global 'foo' variable
| +- foo.txt # help for 'foo' variable
+- resources # resource files (external libraries only)
| +- org
| +- foo
| +- bar.json # static helper data for org.foo.Bar
Add
Name:
Manage Jenkins -> System -> Global Pipeline Libraries
Тhe name is important
net items -> pipeline
‘_’ all import in
@libraty('jenkins-shared-libraty') _
import com.example.Notification
pileline {
agent {
label 'linux'
}
stages {
stage('Demo') {
steps {
script {
def msg = new Notification(this)
withCredentials([string(credentialsId: 'telegram api', variable 'TOKEN')]) {
msg.sendMessage(env. [
chatID: "1564161"
token: "${TOKEN}"]
)
}
}
}
}
}
}