How to clean up pull request directories in jenkins home workspace on jenkins master - jenkins

We use docker containers to build all jobs. So we don't have to worry about cleanup workspace, as container goes away with it. But I see
$JENKINS_HOME/workspace/_job_name_PR-251-4MSWSIVZHFONFLOHNITFTR6R5CAJMNKESIVZHFONFLOHNITFTR6#script
I tried below but did not cleanup
pipeline {
agent {
label 'jenkins-slave'
}
stages {
stage('Build') {
steps {
sh '''npm install
npm run build'''
}
}
}
post { cleanup { cleanWs() } }
}
I can have nightly jenkins job or cron job to delete those directories, looking for better way.

Related

Question on Jenkins BitBucket using pipeline and pipeline script but also running when new data is pushed to bitbucket

I have created an itiem using pipeline, and then in the pipeline selecting the pipeline script,
This allows me to run the build in stages. As below
[code]
pipeline {
agent any
tools {
terraform 'terraform-11'
}
stages {
stage('Git Checkout terraform') {
steps {
git credentialsId: '********', url: 'https://******/********.git'
}
}
stage('Terraform Init') {
steps {
sh 'terraform init'
}
}
stage('Terraform A'){
steps {
dir(dev){
sh 'terraform plan -var-file="terraform.tfvars"'
sh 'terraform apply -auto-approve'
}
}
}
stage('Terraform B'){
steps {
dir(env){
sh 'terraform plan -var-file="terraform.tfvars"'
sh 'terraform apply -auto-approve'
}
}
}
}
}
[/code]
This works very well, I take the code out and run a series of stages. There are more stages than this. What I would like to do is have the jenkins build run every time the terrform scripts are updated. I have look at examples but none of the examples are part of the PipeLine/PipeLine Script
There is Freestyle project, but it does not allow me to build all the stages I need.
There is PipeLine /Pipeline script from SCM which again does not allow me to build all the stages I need.
What I want to do is stick with my current pipeline, but set it so it can be run when scripts are pushed to Bitbucket. All I need is pointing at the right documentation. If this is possible. If its not possible, then I will go back to the drawing board.
I worked out the solution. I set up a Item that is a Folder, set up the Git Repo. Then I created a Jenkins file called JenkinsFile with all the stages and steps. This is then uploaded to the repo being built. So the build will run the main item which the pulls in the JenkinsFile and runs it.

Checkout and run SCM pipeline only on master node

I coded a generic pipeline which accepts several parameters in order to deploy releases from a pre-defined GitHub repository to specific nodes. I wanted to host this pipeline on a Jenkinsfile on GitHub, so I configured the job to work with a "Pipeline script from SCM". The fact is - when I try and build the job - the Jenkinsfile gets checked out on every node. Is it possible to checkout and execute the Jenkinsfile only on, say, the master node and run the pipeline as intended?
EDIT: As I stated before, the pipeline works just fine and as intended setting the job to work with a pipeline script. The thing is when I try and change it to be a "Pipeline script from SCM", the Jenkinsfile gets checked out on every agent, which is a problem since I don't have git installed on any agent other than master. I want the Jenkinsfile to be checked out only on master agent and be executed as intended. FYI the pipeline below:
def agents = "$AGENTS".toString()
def agentLabel = "${ println 'Agents: ' + agents; return agents; }"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
if (agents == null || agents == "") {
println "Skipping build"
skipBuild = true
}
if (!skipBuild) {
println "Agents set for this build: " + agents
}
}
}
}
stage('Powershell deploy script checkout') {
agent { label 'master' }
when {
expression {
!skipBuild
}
}
steps {
git url: 'https://github.com/owner/repo.git', credentialsId: 'git-credentials', branch: 'main'
stash includes: 'deploy-script.ps1', name: 'deploy-script'
}
}
stage('Deploy') {
agent { label agentLabel }
when {
expression {
!skipBuild
}
}
steps {
unstash 'deploy-script'
script {
println "Execute powershell deploy script on agents set for deploy"
}
}
}
}
}
I think that skipDefaultCheckout is what are you looking for:
pipeline {
options {
skipDefaultCheckout true
}
stages {
stage('Prep') {
steps {
script {
........................
}
}
}
}
}
Take a look to the documentation:
skipDefaultCheckout
Skip checking out code from source control by default in the agent directive.
https://www.jenkins.io/doc/book/pipeline/syntax/
I think you are requesting the impossible.
Now:
your Jenkinsfile is inside your jenkins configuration and is sent as such to each of your agents. No need for git on your agents.
Pipeline script for SCM:
Since you use git, SCM = git. So you are saying: my Pipeline needs to be fetched from a git repository. You are declaring the Deploy step to run on agent { label agentLabel }, so that step is supposed to run on another agent than master.
How would you imagine that agent could get the content of the Jenkinsfile to know what to do, but not use git ?
What happens in Jenkins?
Your master agent gets triggered that it needs to build
the master agent checkouts the Jenkinsfile using git (since it is a Pipeline script from SCM)
jenkins reads the Jenkinsfile and sees what has to be done.
for the Prep stage, I'm not quite sure what happens without agent, I guess that runs on master agent.
the Powershell deploy script checkout is marked to run on master agent, so it runs on master agent (note that the Jenkinsfile will get checked out with git two more times:
before starting the stage, because jenkins needs to know what to execute
one more checkout because you specify git url: 'https://github.com/owner/repo.git'...
the Deploy stage is marked to run on agentLabel, so jenkins tries to checkout your Jenkinsfile on that agent (using git)...
You can use Scripted Pipeline to do this, it should basically look like this
node('master') {
checkout scm
stash includes: 'deploy-script.ps1', name: 'deploy-script'
}
def stepsForParallel = [:]
env.AGENTS.split(' ').each { agent ->
stepsForParallel["deploy ${agent}"] = { ->
node(agent) {
unstash 'deploy-script'
}
}
parallel stepsForParallel
you can find all info about jenkins agent section here.
Shortly: you can call any agent by name or label.
pipeline {
agent {
label 'master'
}
}
If it will not work for you, then you will need to set any label on master node and call it by label
pipeline {
agent {
label 'master_label_here'
}
}

Will a Jenkins pipeline compile twice when building a tag?

I want to setup a Jenkins pipeline which builds a Docker image whenever Jenkins is building a tag, so I used buildingTag() in the when condition. This works fine but I have some trouble understanding Jenkins at this point.
Every commit triggers the "Compile" stage. If a tag is built, will the "Compile" stage be executed twice? In a first run on the e.g. master branch and in a second run when explicitly starting the "Tag" build job? If so, how could this be avoided?
pipeline {
agent any
environment {
APP_NAME = 'myapp'
}
stages {
stage('Compile') {
steps {
echo "Start compiling..."
}
}
stage('Build Docker Image') {
when { buildingTag() }
steps {
echo "Building a Docker image..."
}
}
}
}
For a multibranch project branch builds are separate from tag builds, so yes, each build would have the compile stage running. They will also have separate workspaces, so they should not affect each other.
If you don't want a stage to run at tag build, just add a when { not { buildingTag() } } expression to that stage.

Jenkins Declarative Pipeline - SCM

I am taking some Jenkins tutorial. The sample code I read is
pipeline {
agent none
stages {
stage('Build') {
agent {
docker {
image 'python:2-alpine'
}
}
steps {
sh 'python -m py_compile sources/add2vals.py sources/calc.py'
}
}
stage('Test') {
agent {
docker {
image 'qnib/pytest'
}
}
steps {
sh 'py.test --verbose --junit-xml test-reports/results.xml sources/test_calc.py'
}
post {
always {
junit 'test-reports/results.xml'
}
}
}
stage('Deliver') {
agent {
docker {
image 'cdrx/pyinstaller-linux:python2'
}
}
steps {
sh 'pyinstaller --onefile sources/add2vals.py'
}
post {
success {
archiveArtifacts 'dist/add2vals'
}
}
}
}
}
So basically there are three steps Build, Test and Deliver. They all use different images to generate different containers. But this Jenkins job is configured to use the Git as the SCM.
So if this Jenkins build is run, says the project is built on the first container. Then the second stage is testing the project on another container, followed by the deliver on the third container. How does this Jenkins job make sure that these three steps are performing on the code sequentially.
Based on my understanding, each stage needs to perform git clone/git pull, and before the stage finishes, the git push is required.
If SCM IS configured through Jenkins to use Git, do we need to include the git clone/git pull', as well as 'git push' in the corresponding shell scripts(understeps, or it it already taken into consideration by theSCM` function of Jenkins?
Thanks
In this case, you must ensure that the binary that is in the QA environment must be the same as it should be in the UAT environment and then in Production.
For this, you must use an artifact repository or registry (Artifactory, Nexus, Docker Registry, etc.) to promote the artifacts to the Production environment.
See this link and see how it was done in the Pipeline.

Jenkins pipeline working in different folders

Alright so I am just learning about pipelines in Jenkins and I've ran into a small problem.
It is building my war file in one directory but trying to build the docker image in another one, which will ofcourse fail.
so a shorthand log describes the problem quite well:
[Pipeline] stage
[Pipeline] { (build war)
[Pipeline] node
Running on Jenkins in /root/.jenkins/workspace/Wunderbaren#2
[Pipeline] {
[Pipeline] stage
[Pipeline] { (build dockerimage)
[Pipeline] script
[Pipeline] {
[Pipeline] dir
Running in /root/.jenkins/workspace/Wunderbaren/backend
[Pipeline] {
the Jenkinsfile:
pipeline {
agent any
stages {
stage('build war') {
agent {
docker { image 'gradle:latest' }
}
steps {
sh 'gradle war -b backend/build.gradle'
}
}
stage('build dockerimage') {
steps {
script {
dir('backend/') {
def image = docker.build("munhunger/wunderbaren")
docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
image.push("${env.BUILD_NUMBER}")
image.push("latest")
}
}
}
}
}
}
}
What I find odd is that I have a similar project with pretty much the exact same configuration. only differs in folder names and docker tag. And that seems to be working 100% of the times, so I feel quite lost on this one!
Turns out you need to reuse the node:
stage('build war') {
agent {
docker {
image 'gradle:latest'
reuseNode true
}
}
steps {
sh 'gradle war -b backend/build.gradle'
}
}
From the documentation I found at https://go.cloudbees.com/docs/cloudbees-documentation/use/reference/pipeline/
reuseNode
A boolean, false by default. If true, run the container in the node specified at the top-level of the Pipeline, in the same workspace, rather than on a new node entirely.
This option is valid for docker and dockerfile, and only has an effect when used on an agent for an individual stage.
From Jenkins Pipeline Documentation
The agent section specifies where the entire Pipeline, or a specific stage, will execute in the Jenkins environment depending on where the agent section is placed. The section must be defined at the top-level inside the pipeline block, but stage-level usage is optional.
I believe this means the 'build war' stage will execute in a separate environment from the 'build docker image' stage. As far as similar syntax working in a different job, perhaps the same agent is defined for both stages?

Resources