Jenkinsfile | Multibranch Pipeline - jenkins

Below is my pipeline:-
#!groovy
String version
String awsRegion = "us-east-1"
String appName = "abcde"
String dockerFilePath = "."
def featureEnv = env.BRANCH_NAME != 'master'
String branchName = env.BRANCH_NAME
String env = (env.BRANCH_NAME == 'master') ? 'release' : 'develop'
String ecrRepo = featureEnv ? "123456789012.dkr.ecr.${awsRegion}.amazonaws.com/abcde_${env}" : "987654321098.dkr.ecr.${awsRegion}.amazonaws.com/abcde_master"
String terraformPath = "terraform/dev"
println "Feature Environment=${featureEnv}"
pipeline {
agent none
options {
buildDiscarder(logRotator(numToKeepStr: '30'))
disableConcurrentBuilds()
timeout(time: 6, unit: 'HOURS')
ansiColor('xterm')
}
stages {
stage('version build'){
agent { label 'linux' }
steps {
script {
version = VersionNumber(
versionNumberString: '1.0.${BUILD_NUMBER, X}',
skipFailedBuilds: false)
currentBuild.displayName = version
println "Pipeline Version='${version}'"
}
}
}
stage('Build') {
when {
anyOf { branch 'develop'; branch 'release' }
}
agent { label 'linux' }
steps {
checkout scm
unstash name: "${appName}-docker"
dir(dockerFilePath) {
sh("""
while IFS= read -r line; do
build_args+=" --build-arg \$line"
done < "env_vars.txt"
#echo \$build_args
docker build -t ${ecrRepo}:${version} \$build_args --no-cache=true .
eval \$(aws ecr get-login --no-include-email --region ${awsRegion})
docker push ${ecrRepo}:${version}
docker rmi ${ecrRepo}:${version}
""")
}
}
}
}
}
I am using Multibranch pipelines to execute Jenkins job but for branch release, Its by default taking develop branch i am attaching docker build and docker push outputs of Jenkins instead release ECR repo. Please suggest.
Jenkins Output:-
+ docker build -t 123456789012.dkr.ecr.us-east-1.amazonaws.com/abcde_develop:1.0.2 --build-arg HOST=0.0.0.0 --build-arg PORT=8080 --build-arg DOMAIN=abcde --build-arg MSAL_CLIENT_ID=1234567-bd11-4d2e-add5-d78f5e59e976 --build-arg
+ docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/abcde_develop:1.0.2

Suppose you can use for test purpose this version
when {
expression { BRANCH_NAME ==~ /(develop|release)/ }
}

Related

Transfer data between stages on Jenkins Pipeline

Am I able somehow to copy data from one stage for usage on another?
For example, I have one stage where I want to clone my repo, and on another run the Kaniko which will copy (on dockerfile) all data to container and build it
How to do this? Because
Stages are independent and I not able to operate via the same data on both
on Kaniko I not able to install the GIT to clone it there
Thanks in advance
Example of code :
pipeline {
agent none
stages {
stage('Clone repository') {
agent {
label 'builder'
}
steps {
sh 'git clone ssh://git#myrepo.com./repo.git'
sh 'cd repo'
}
}
stage('Build application') {
agent {
docker {
label 'builder'
image 'gcr.io/kaniko-project/executor:debug'
args '-u 0 --entrypoint=""'
}
}
steps {
sh '''#!/busybox/sh
/kaniko/executor -c `pwd` -f Dockerfile"
'''
}
}
}
}
P.S. On dockerfile I using such as
ADD . /
You can try to use stash:
stage('Clone repository') {
agent {
label 'builder'
}
steps {
sh 'git clone ssh://git#myrepo.com./repo.git'
script {
stash includes: 'repo/', name: 'myrepo'
}
}
}
stage('Build application') {
agent {
docker {
label 'builder'
image 'gcr.io/kaniko-project/executor:debug'
args '-u 0 --entrypoint=""'
}
}
steps {
script {
unstash 'myrepo'
}
sh '''#!/busybox/sh
/kaniko/executor -c `pwd` -f Dockerfile"
'''
}

Jenkins adding additional . to tagging

I have a sample jenkins script which I am using to build my image
pipeline {
environment{
registry = "leexha/sampleadd"
registyCredential = 'dockerhub'
dockerImage = ''
}
agent any
stages {
stage('Git clone'){
steps{
git branch: 'master', url: 'https://github.com/leeadh/terraform_simpleapp.git'
}
}
stage ('Building image'){
steps{
script{
dockerImage = docker.build(registry + ":development .","--build-arg endpoint_arg='http://22222:8200' --build-arg token_arg='s.aaaaa'")
}
}
}
stage ('Pushing to Docker Hub'){
steps{
script{
println dockerImage.id
docker.withRegistry('',registyCredential){
dockerImage.push()
}
}
}
}
}
}
the build is successful. However when I println the dockerImage under the stage ('Pushing to Docker Hub') i notice it states that
leexha/sampleadd:development .
As a result tagging fails and it cant push. Im wondering why it puts an additional . at the end of the image when I did not put it anywhere.
in line
dockerImage = docker.build(registry + ":development .","--build-arg endpoint_arg='http://22222:8200' --build-arg token_arg='s.aaaaa'")
if i dont put the . after development, the build will fail.

Pass a string parameter to Jenkins declarative script

I am declaring a String Parameter in Jenkins -
Name is SLACKTOKEN
Value is qwsaw2345
My Jenkins file has script
pipeline {
agent { label 'trial' }
stages {
stage("Build Docker Image") {
steps{
sh 'docker build -t trial:latest --build-arg SLACK_SIGNING_SECRET=${SLACKTOKEN}'
}
}
}
}
I tried like this, but it didnt work. Could you please let me know how can I pass a value from Jenkins string parameter to Jenkins declarative script file.
I have added the Password parameter in job like below
Inside parameters directive you can provide parameters, details is here.
To pass parameter use params.SLACKTOKEN inside double quotes, not single:
pipeline {
agent { label 'trial' }
parameters {
password(name: 'SLACKTOKEN', defaultValue: '', description: 'Slack Token')
}
stages {
stage("Build Docker Image") {
steps{
sh "docker build -t trial:latest --build-arg SLACK_SIGNING_SECRET=${params.SLACKTOKEN}"
}
}
}
}
Where have you declared your variable?
There are a lot of options:
Example: Use env section from declarative syntax:
pipeline {
agent {
label 'trial'
}
environment {
SLACKTOKEN = 'qwsaw2345'
}
stages {
stage('Build') {
steps {
sh "docker build -t trial:latest --build-arg SLACK_SIGNING_SECRET=${SLACKTOKEN}"
}
}
}
}

Using a dockerfile with Jenkins Scripted Pipeline Syntax

Using Jenkins Declarative Pipeline, one can easily specify a Dockerfile, agent label, build args and run args as follows:
Jenkinsfile (Declarative Pipeline)
agent {
dockerfile {
dir './path/to/dockerfile'
label 'my-label'
additionalBuildArgs '--build-arg version=1.0'
args '-v /tmp:/tmp'
}
}
I am trying to achieve the same using the scripted pipeline syntax. I found a way to pass the agent label and run args, but was unable to to pass the directory and build args. Ideally, I would write something like this (label and run args are already working):
Jenkinsfile (Scripted Pipeline)
node ("my-label"){
docker.dockerfile(
dir: './path/to/dockerfile',
additionalBuildArgs:'--build-arg version=1.0'
).inside('-v /tmp:/tmp') {
\\ add stages here
}
}
The documentation shows how this can be done using an existing docker image, i.e., with the image directive in the pipeline.
Jenkinsfile (Declarative Pipeline)
pipeline {
agent {
docker { image 'node:7-alpine' }
}
stage('Test') {
//...
}
}
Jenkinsfile (Scripted Pipeline)
node {
docker.image('node:7-alpine').inside {
stage('Test') {
//...
}
}
}
However, the scripted pipeline syntax for the dockerfile directive is missing.
The workaround I am using at the moment is building the image myself.
node ("my-label"){
def testImage = docker.build(
"test-image",
"./path/to/dockerfile",
"--build-arg v1.0"
)
testImage.inside('-v /tmp:/tmp') {
sh 'echo test'
}
}
Any help is much appreciated!
I personally put the docker cli arguments before the image folder path and would specify the docker filename with -f argument
Apart from that, you are doing this the right way. agent dockerfile is building a docker image the same way docker.build step is doing. Except you can push your image to a registry by using the docker.build step
Here is I how do
def dockerImage
//jenkins needs entrypoint of the image to be empty
def runArgs = '--entrypoint \'\''
pipeline {
agent {
label 'linux_x64'
}
options {
buildDiscarder(logRotator(numToKeepStr: '100', artifactNumToKeepStr: '20'))
timestamps()
}
stages {
stage('Build') {
options { timeout(time: 30, unit: 'MINUTES') }
steps {
script {
def commit = checkout scm
// we set BRANCH_NAME to make when { branch } syntax work without multibranch job
env.BRANCH_NAME = commit.GIT_BRANCH.replace('origin/', '')
dockerImage = docker.build("myImage:${env.BUILD_ID}",
"--label \"GIT_COMMIT=${env.GIT_COMMIT}\""
+ " --build-arg MY_ARG=myArg"
+ " ."
)
}
}
}
stage('Push to docker repository') {
when { branch 'master' }
options { timeout(time: 5, unit: 'MINUTES') }
steps {
lock("${JOB_NAME}-Push") {
script {
docker.withRegistry('https://myrepo:5000', 'docker_registry') {
dockerImage.push('latest')
}
}
milestone 30
}
}
}
}
}
Here is a purely old-syntax scripted pipeline that solves the problem of checking out, building a docker image and pushing the image to a registry. It assumes the Jenkins project is type "Pipeline script from SCM".
I developed this pipeline for a server that requires proxies to reach the public internet. The Dockerfile accepts build arguments to configure its tools for proxies.
I think this has a pretty good structure #fredericrous :) but I'm new to pipelines, please help me improve!
def scmvars
def image
node {
stage('clone') {
// enabled by project type "Pipeline script from SCM"
scmvars = checkout(scm)
echo "git details: ${scmvars}"
}
stage('env') {
// Jenkins provides no environment variable view
sh 'printenv|sort'
}
stage('build') {
// arg 1 is the image name and tag
// arg 2 is docker build command line
image = docker.build("com.mycompany.myproject/my-image:${env.BUILD_ID}",
" --build-arg commit=${scmvars.GIT_COMMIT}"
+ " --build-arg http_proxy=${env.http_proxy}"
+ " --build-arg https_proxy=${env.https_proxy}"
+ " --build-arg no_proxy=${env.no_proxy}"
+ " path/to/dir/with/Dockerfile")
}
stage('push') {
docker.withRegistry('https://registry.mycompany.com:8100',
'jenkins-registry-credential-id') {
image.push()
}
}
}

How to push an openshift built container image to a private registry through a Jenkinsfile

Using the OpenShift oc new-app command, I have built a container image. Instead of pushing the image to a local container registry, I want to push the generated image to a private registry. As I am using Jenkins for CI/CD, I want to automate the process of generating the image and pushing to the private registry.
I am able to achieve the generation part. But struck with pushing the image to a private registry through Jenkinsfile. Any pointers on how to achieve this is appreciated.
This Jenkins Building Docker Image and Sending to Registry article discusses how this might be done.
pipeline {
environment {
registry = "gustavoapolinario/docker-test"
registryCredential = 'dockerhub'
dockerImage = ''
}
agent any
tools {nodejs "node" }
stages {
stage('Cloning Git') {
steps {
git 'https://github.com/gustavoapolinario/node-todo-frontend'
}
}
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Building image') {
steps{
script {
dockerImage = docker.build registry + ":$BUILD_NUMBER"
}
}
}
stage('Deploy Image') {
steps{
script {
docker.withRegistry( '', registryCredential ) {
dockerImage.push()
}
}
}
}
stage('Remove Unused docker image') {
steps{
sh "docker rmi $registry:$BUILD_NUMBER"
}
}
}
}

Resources