工作空间管理 #

工作空间(Workspace)是Jenkins执行构建任务的目录,理解和管理好工作空间对于构建效率和磁盘空间都很重要。

什么是工作空间? #

工作空间是Jenkins为每个任务分配的目录,用于:

  • 存放检出的源代码
  • 执行构建过程
  • 存放构建产物
text
JENKINS_HOME/
├── workspace/
│   ├── my-pipeline/           # 任务工作空间
│   │   ├── src/
│   │   ├── target/
│   │   └── pom.xml
│   ├── my-pipeline@2/         # 并行构建工作空间
│   └── another-job/
└── jobs/
    └── my-pipeline/
        ├── builds/
        └── config.xml

工作空间路径 #

默认路径 #

text
${JENKINS_HOME}/workspace/${JOB_NAME}

自定义路径 #

groovy
pipeline {
    agent {
        node {
            label 'linux'
            customWorkspace '/tmp/custom-workspace'
        }
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'pwd'
            }
        }
    }
}

动态路径 #

groovy
pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                ws("workspace/${BUILD_NUMBER}") {
                    sh 'pwd'
                }
            }
        }
    }
}

工作空间变量 #

内置变量 #

变量 说明
WORKSPACE 当前工作空间路径
WORKSPACE_TMP 临时工作空间路径

使用示例 #

groovy
steps {
    echo "工作空间: ${WORKSPACE}"
    echo "临时目录: ${WORKSPACE_TMP}"
    
    dir("${WORKSPACE}/subdir") {
        sh 'pwd'
    }
}

清理工作空间 #

cleanWs步骤 #

groovy
steps {
    cleanWs()
}

条件清理 #

groovy
post {
    always {
        cleanWs cleanWhenSuccess: false,
                cleanWhenFailure: true,
                cleanWhenUnstable: true,
                cleanWhenAborted: true
    }
}

清理特定文件 #

groovy
steps {
    cleanWs patterns: [
        [pattern: 'target/**', type: 'INCLUDE'],
        [pattern: 'node_modules/**', type: 'INCLUDE'],
        [pattern: '.git/**', type: 'EXCLUDE']
    ]
}

删除目录 #

groovy
steps {
    dir('target') {
        deleteDir()
    }
    
    sh 'rm -rf node_modules'
}

构建前清理 #

Pipeline选项 #

groovy
pipeline {
    agent any
    
    options {
        skipDefaultCheckout()
    }
    
    stages {
        stage('Checkout') {
            steps {
                cleanWs()
                checkout scm
            }
        }
    }
}

Git清理 #

groovy
steps {
    checkout([
        $class: 'GitSCM',
        branches: [[name: '*/main']],
        extensions: [
            [$class: 'CleanBeforeCheckout'],
            [$class: 'WipeWorkspace']
        ],
        userRemoteConfigs: [[
            url: 'https://github.com/user/repo.git'
        ]]
    ])
}

Git扩展 #

groovy
extensions: [
    [$class: 'CleanBeforeCheckout'],
    [$class: 'CleanCheckout'],
    [$class: 'WipeWorkspace'],
    [$class: 'PruneStaleBranch']
]

并行构建工作空间 #

问题 #

当同一任务并行执行时,需要独立的工作空间。

自动处理 #

Jenkins自动为并行构建创建独立工作空间:

text
workspace/
├── my-pipeline/      # 构建 #1
├── my-pipeline@2/    # 构建 #2
├── my-pipeline@3/    # 构建 #3
└── ...

手动指定 #

groovy
pipeline {
    agent any
    
    options {
        disableConcurrentBuilds()
    }
    
    stages {
        stage('Build') {
            steps {
                ws("build-${BUILD_NUMBER}") {
                    sh 'mvn clean package'
                }
            }
        }
    }
}

工作空间共享 #

stash/unstash #

groovy
stage('Build') {
    steps {
        sh 'mvn clean package'
        stash includes: 'target/*.jar', name: 'artifacts'
    }
}

stage('Deploy') {
    agent { label 'production' }
    steps {
        unstash 'artifacts'
        sh 'deploy.sh'
    }
}

多阶段共享 #

groovy
pipeline {
    agent none
    
    stages {
        stage('Build') {
            agent { label 'build' }
            steps {
                sh 'mvn clean package'
                stash includes: 'target/*.jar', name: 'artifacts'
                stash includes: 'src/**', name: 'source'
            }
        }
        
        stage('Test') {
            agent { label 'test' }
            steps {
                unstash 'artifacts'
                unstash 'source'
                sh 'mvn test'
            }
        }
        
        stage('Deploy') {
            agent { label 'deploy' }
            steps {
                unstash 'artifacts'
                sh 'deploy.sh'
            }
        }
    }
}

磁盘空间管理 #

构建历史清理 #

groovy
pipeline {
    agent any
    
    options {
        buildDiscarder(logRotator(
            numToKeepStr: '10',
            artifactNumToKeepStr: '5',
            daysToKeepStr: '30'
        ))
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
}

工作空间清理策略 #

groovy
pipeline {
    agent any
    
    options {
        buildDiscarder(logRotator(numToKeepStr: '10'))
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
    
    post {
        always {
            cleanWs()
        }
    }
}

系统级配置 #

  1. 进入 Manage Jenkins → System
  2. 配置 Workspace Root Directory
  3. 配置 Build Record Root Directory
text
Workspace Root Directory: ${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}
Build Record Root Directory: ${ITEM_ROOT_DIR}/builds

工作空间监控 #

磁盘使用 #

groovy
steps {
    script {
        def workspace = env.WORKSPACE
        def size = sh(script: "du -sh ${workspace}", returnStdout: true).trim()
        echo "Workspace size: ${size}"
    }
}

磁盘阈值检查 #

groovy
stage('Check Disk') {
    steps {
        script {
            def workspace = env.WORKSPACE
            def sizeKB = sh(script: "du -sk ${workspace} | cut -f1", returnStdout: true).trim().toInteger()
            def maxSizeKB = 1024 * 1024  // 1GB
            
            if (sizeKB > maxSizeKB) {
                echo "Warning: Workspace size (${sizeKB / 1024}MB) exceeds threshold"
            }
        }
    }
}

目录操作 #

dir步骤 #

groovy
steps {
    dir('subdirectory') {
        sh 'pwd'
    }
    
    dir('/tmp/absolute/path') {
        sh 'pwd'
    }
}

嵌套目录 #

groovy
steps {
    dir('project') {
        dir('src') {
            sh 'pwd'
        }
    }
}

动态目录 #

groovy
steps {
    script {
        def dirs = ['dir1', 'dir2', 'dir3']
        dirs.each { d ->
            dir(d) {
                sh "echo 'In ${d}'"
            }
        }
    }
}

文件操作 #

创建目录 #

groovy
steps {
    sh 'mkdir -p target/classes'
    
    dir('target/classes') {
        sh 'pwd'
    }
}

复制文件 #

groovy
steps {
    sh 'cp -r src/main/resources target/classes'
}

移动文件 #

groovy
steps {
    sh 'mv target/*.jar dist/'
}

最佳实践 #

1. 及时清理 #

groovy
pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
    
    post {
        always {
            cleanWs()
        }
    }
}

2. 使用clean目标 #

groovy
steps {
    sh 'mvn clean package'  // Maven clean
    sh 'gradle clean build' // Gradle clean
    sh 'npm run clean'      // npm clean
}

3. 限制构建历史 #

groovy
options {
    buildDiscarder(logRotator(numToKeepStr: '10'))
}

4. 使用.gitignore #

groovy
steps {
    sh '''
        git clean -fdx
        git reset --hard
    '''
}

5. 分离构建和部署 #

groovy
pipeline {
    agent none
    
    stages {
        stage('Build') {
            agent { label 'build' }
            steps {
                sh 'mvn clean package'
                stash 'artifacts'
            }
            post {
                always {
                    cleanWs()
                }
            }
        }
        
        stage('Deploy') {
            agent { label 'deploy' }
            steps {
                unstash 'artifacts'
                sh 'deploy.sh'
            }
            post {
                always {
                    cleanWs()
                }
            }
        }
    }
}

完整示例 #

groovy
pipeline {
    agent any
    
    tools {
        maven 'Maven 3.8'
        jdk 'JDK 11'
    }
    
    options {
        buildDiscarder(logRotator(
            numToKeepStr: '20',
            artifactNumToKeepStr: '5'
        ))
        timeout(time: 30, unit: 'MINUTES')
        skipDefaultCheckout()
    }
    
    environment {
        APP_NAME = 'myapp'
        VERSION = "${BUILD_NUMBER}"
    }
    
    stages {
        stage('Checkout') {
            steps {
                cleanWs()
                checkout([
                    $class: 'GitSCM',
                    branches: [[name: '*/main']],
                    extensions: [
                        [$class: 'CleanBeforeCheckout'],
                        [$class: 'CloneOption', depth: 1, shallow: true]
                    ],
                    userRemoteConfigs: [[
                        url: 'https://github.com/user/repo.git'
                    ]]
                ])
            }
        }
        
        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit '**/target/surefire-reports/*.xml'
                }
            }
        }
        
        stage('Archive') {
            steps {
                archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
                stash includes: 'target/*.jar', name: 'artifacts'
            }
        }
        
        stage('Deploy') {
            agent { label 'production' }
            steps {
                unstash 'artifacts'
                
                withCredentials([file(credentialsId: 'kube-config', variable: 'KUBECONFIG')]) {
                    sh """
                        kubectl set image deployment/${APP_NAME} \
                            ${APP_NAME}=registry.example.com/${APP_NAME}:${VERSION}
                    """
                }
            }
            post {
                always {
                    cleanWs()
                }
            }
        }
    }
    
    post {
        always {
            script {
                def size = sh(script: "du -sh ${WORKSPACE} 2>/dev/null || echo '0'", returnStdout: true).trim()
                echo "Final workspace size: ${size}"
            }
        }
        cleanup {
            cleanWs(
                cleanWhenSuccess: true,
                cleanWhenFailure: true,
                deleteDirs: true,
                disableDeferredWipeout: true
            )
        }
    }
}

下一步学习 #

小结 #

  • 工作空间是构建执行目录
  • 及时清理避免磁盘空间问题
  • 使用stash/unstash在节点间传递文件
  • 合理配置构建历史保留策略
  • 并行构建使用独立工作空间
  • 遵循最佳实践管理磁盘空间
最后更新:2026-03-28