187

We are running Jenkins 2.x and love the new Pipeline plugin. However, with so many branches in a repository, disk space fills up quickly.

Is there any plugin that's compatible with Pipeline that I can wipe out the workspace on a successful build?

Andrew Gray
  • 3,593
  • 3
  • 35
  • 62
qmo
  • 3,128
  • 3
  • 17
  • 23

15 Answers15

161

Like @gotgenes pointed out with Jenkins Version. 2.74, the below works, not sure since when, maybe if some one can edit and add the version above

cleanWs()

With, Jenkins Version 2.16 and the Workspace Cleanup Plugin, that I have, I use

step([$class: 'WsCleanup'])

to delete the workspace.

You can view it by going to

JENKINS_URL/job/<any Pipeline project>/pipeline-syntax

Then selecting "step: General Build Step" from Sample step and then selecting "Delete workspace when build is done" from Build step

cursed_axes
  • 1,753
  • 1
  • 12
  • 12
  • This works for me: Jenkins 2.7.2, Workspace Cleanup Plugin 0.30 – dsh Aug 24 '16 at 21:31
  • 4
    According to [this PR](https://github.com/jenkinsci/ws-cleanup-plugin/pull/30/files#diff-4b88580f361d14ff592e5f06a99026ccR258), included in [0.33](https://wiki.jenkins.io/display/JENKINS/Workspace+Cleanup+Plugin#WorkspaceCleanupPlugin-Release0.33(2017-04-24)), this is called in the pipeline as `cleanWs`. – gotgenes Sep 18 '17 at 18:51
137

The mentioned solutions deleteDir() and cleanWs() (if using the workspace cleanup plugin) both work, but the recommendation to use it in an extra build step is usually not the desired solution. If the build fails and the pipeline is aborted, this cleanup-stage is never reached and therefore the workspace is not cleaned on failed builds.

=> In most cases you should probably put it in a post-built-step condition like always:

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
    post { 
        always { 
            cleanWs()
        }
    }
}
Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82
MattDiMu
  • 4,873
  • 1
  • 19
  • 29
  • 6
    This was absolutely key for my use case. I need to archive artifacts from the job, and running `cleanWs()` as a step deletes them before the post build archive command runs. `cleanWs()` should most likely always be run as a post build command – Brandon Jan 05 '18 at 23:55
  • 35
    If you have only one `post` section, `cleanWs()` can safely be put into the `always` condition, but the safest spot is inside the `cleanup` condition: `post { cleanup { cleanWs() } }` – ᴠɪɴᴄᴇɴᴛ Jun 13 '18 at 15:54
128

You can use deleteDir() as the last step of the pipeline Jenkinsfile (assuming you didn't change the working directory).

Krzysztof Krasoń
  • 26,515
  • 16
  • 89
  • 115
  • 10
    I have problems with deleteDir(). It seems to randomly not able to delete the current directory when the node gets build on a slave. The build fails of course if this happens. So be aware if your jobs fail randomly. I don't understand why node not just cleans it workspace when the node starts building. Because the node can run anywhere you can't make any assumptions about the files in the workspace anyway. – ssindelar Jul 07 '16 at 13:39
  • 1
    But I think will only delete the workspace on the current node. In the general case your pipeline will runs on several different slaves. – Marcus Philip Aug 23 '16 at 13:45
  • 26
    I put this at the beggining right before `checkout scm`. – jpbochi Sep 05 '16 at 10:59
  • 2
    I put this at the beginning also, in case the project fails before it reaches the end, or the next build is on a different slave. – davegallant Nov 23 '16 at 14:47
  • 2
    This is the command documented to clean up the workspace in the ["Cleaning up and notifications"](https://jenkins.io/doc/pipeline/tour/post/) section of the Jenkins documentation. – vossad01 Jan 21 '18 at 03:03
  • 1
    Beware `deleteDir()` won't work in a docker container. [JENKINS-41894](https://issues.jenkins-ci.org/browse/JENKINS-41894) – boweeb Jun 26 '19 at 16:51
72

In fact the deleteDir function recursively deletes the current directory and its contents. Symbolic links and junctions will not be followed but will be removed.

To delete a specific directory of a workspace wrap the deleteDir step in a dir step.

dir('directoryToDelete') {
    deleteDir()
}
Sebastien
  • 1,057
  • 8
  • 7
34

Using the following pipeline script:

pipeline {
    agent { label "master" }
    options { skipDefaultCheckout() }
    stages {
        stage('CleanWorkspace') {
            steps {
                cleanWs()
            }
        }
    }
}

Follow these steps:

  1. Navigate to the latest build of the pipeline job you would like to clean the workspace of.
  2. Click the Replay link in the LHS menu.
  3. Paste the above script in the text box and click Run
Andrew Gray
  • 3,593
  • 3
  • 35
  • 62
29

I used deleteDir() as follows:

  post {
        always {
            deleteDir() /* clean up our workspace */
        }
    }

However, I then had to also run a Success or Failure AFTER always but you cannot order the post conditions. The current order is always, changed, aborted, failure, success and then unstable.

However, there is a very useful post condition, cleanup which always runs last, see https://jenkins.io/doc/book/pipeline/syntax/

So in the end my post was as follows :

post {
    always {

    }
    success{

    }
    failure {

    }
    cleanup{
        deleteDir()
    }
}

Hopefully this may be helpful for some corner cases

user3586383
  • 299
  • 3
  • 5
  • 1
    We get an error "invalid condition cleanup", we are using Jenkins version 2.89 – Aravind Murthy Dec 07 '18 at 08:20
  • In my opnion, this is one of the best answer, however, I would recommand to not delete the data in the failing case such as you are keeping debug data. Moreover, deleting the data at the beginning is also a good solution. – White Sep 21 '21 at 11:14
17

If you have used custom workspace in Jenkins then deleteDir() will not delete @tmp folder.

So to delete @tmp along with workspace use following

pipeline {
    agent {
        node {
            customWorkspace "/home/jenkins/jenkins_workspace/${JOB_NAME}_${BUILD_NUMBER}"
        }
    }
    post {
        cleanup {
            /* clean up our workspace */
            deleteDir()
            /* clean up tmp directory */
            dir("${workspace}@tmp") {
                deleteDir()
            }
            /* clean up script directory */
            dir("${workspace}@script") {
                deleteDir()
            }
        }
    }
}

This snippet will work for default workspace also.

Pankaj Shinde
  • 3,361
  • 2
  • 35
  • 44
9

Using the 'WipeWorkspace' extension seems to work as well. It requires the longer form:

checkout([
   $class: 'GitSCM',
   branches: scm.branches,
   extensions: scm.extensions + [[$class: 'WipeWorkspace']],
   userRemoteConfigs: scm.userRemoteConfigs
])

More details here: https://support.cloudbees.com/hc/en-us/articles/226122247-How-to-Customize-Checkout-for-Pipeline-Multibranch-

Available GitSCM extensions here: https://github.com/jenkinsci/git-plugin/tree/master/src/main/java/hudson/plugins/git/extensions/impl

blindsnowmobile
  • 3,868
  • 6
  • 32
  • 47
8

For Jenkins 2.190.1 this works for sure:

    post {
        always {
            cleanWs deleteDirs: true, notFailBuild: true
        }
    }
MAZux
  • 911
  • 1
  • 15
  • 28
7
pipeline {
    agent any

    tools {nodejs "node"}
    
    environment {

    }

    parameters {
        string(name: 'FOLDER', defaultValue: 'ABC', description: 'FOLDER', trim: true)

    }

    stages {
        stage('1') {
            steps{
            }
        }
        stage("2") {
            steps {
            }     
        }
    }
    post {
        always {
            echo "Release finished do cleanup and send mails"
            deleteDir()
        }
        success {
            echo "Release Success"
        }
        failure {
            echo "Release Failed"
        }
        cleanup {
            echo "Clean up in post work space"
            cleanWs()
        }
    }
}
Sachin Nikumbh
  • 911
  • 11
  • 11
4

We make sure we are working with a clean workspace by using a feature of the git plugin. You can add additional behaviors like 'Clean before checkout'. We use this as well for 'Prune stale remote-tracking branches'.

NOTtardy
  • 154
  • 6
3

In my case, I want to clear out old files at the beginning of the build, but this is problematic since the source code has been checked out.

My solution is to ask git to clean out any files (from the last build) that it doesn't know about:

    sh "git clean -x -f"

That way I can start the build out clean, and if it fails, the workspace isn't cleaned out and therefore easily debuggable.

djhaskin987
  • 9,741
  • 4
  • 50
  • 86
2

Cleaning up : Since the post section of a Pipeline is guaranteed to run at the end of a Pipeline’s execution, we can add some notification or other steps to perform finalization, notification, or other end-of-Pipeline tasks.

pipeline {
    agent any
    stages {
        stage('No-op') {
            steps {
                sh 'ls'
            }
        }
    }
    post {
        cleanup {
            echo 'One way or another, I have finished'
            deleteDir() /* clean up our workspace */
        }
    }
}
Community
  • 1
  • 1
YourAboutMeIsBlank
  • 1,787
  • 3
  • 18
  • 27
1

Currently both deletedir() and cleanWs() do not work properly when using Jenkins kubernetes plugin, the pod workspace is deleted but the master workspace persists

it should not be a problem for persistant branches, when you have a step to clean the workspace prior to checkout scam. It will basically reuse the same workspace over and over again: but when using multibranch pipelines the master keeps the whole workspace and git directory

I believe this should be an issue with Jenkins, any enlightenment here?

0

I usually use this:

post {
        success {
            cleanWs()
        }
    }
himneh
  • 96
  • 6