Caching Dependencies and Managing Artifacts

Cache dependencies with stash/unstash or an external cache to skip redundant downloads, and archive only the build outputs that matter.

The fastest build step is the one you skip. Two related ideas keep pipelines quick and tidy: caching inputs and archiving outputs deliberately.

stash and unstash

Within a single run, stash saves a set of files on the controller and unstash restores them on another agent — perfect for handing a compiled artifact from a Build stage to a parallel set of Test agents without rebuilding. Stashes are scoped to the build and cleaned up automatically, so they are for intra-run handoff, not long-term storage.

Real caching across builds

Stash is not a dependency cache. For that, mount a persistent volume on ephemeral agents (e.g. a shared ~/.m2 or node_modules cache PVC), or push to an external cache/artifact server such as Nexus, Artifactory, or an S3 bucket keyed by a lockfile hash. That is what survives across builds and across ephemeral agents.

Archive with intent

Use archiveArtifacts for the handful of outputs a human might download — a jar, a coverage report, a built image manifest. Archiving your entire node_modules just fills the controller disk. Pair it with buildDiscarder so old artifacts age out.

Example

Example · bash
pipeline {
    agent none
    stages {
        stage('Build') {
            agent { label 'linux' }
            steps {
                sh 'npm ci && npm run build'
                // hand the build output to later stages without rebuilding
                stash name: 'dist', includes: 'dist/**'
            }
        }
        stage('Test shards') {
            parallel {
                stage('shard-1') {
                    agent { label 'linux' }
                    steps { unstash 'dist'; sh 'npm run test:shard1' }
                }
                stage('shard-2') {
                    agent { label 'linux' }
                    steps { unstash 'dist'; sh 'npm run test:shard2' }
                }
            }
        }
        stage('Publish') {
            agent { label 'linux' }
            steps {
                unstash 'dist'
                // keep only what a human might download later
                archiveArtifacts artifacts: 'dist/app.tar.gz', fingerprint: true
            }
        }
    }
}

When to use it

  • A Maven build caches the ~/.m2 repository on a shared NFS volume so each build skips downloading 300 MB of dependencies.
  • A Node.js pipeline uses stash/unstash to pass the compiled dist/ folder from the build agent to a dedicated deploy agent.
  • Only the final JAR and its SHA-256 are archived rather than the entire target/ directory, saving significant disk space per build.

More examples

Maven local repo cache on agent

Points Maven at a persistent cache directory on the agent so dependency downloads are skipped on subsequent builds.

Example · groovy
pipeline {
  agent any
  options {
    // workspace is on an agent with a persistent maven cache volume
  }
  stages {
    stage('Build') {
      steps {
        sh 'mvn -Dmaven.repo.local=/cache/m2 package'
      }
    }
  }
}

Stash and unstash between agents

Stashes build outputs from the builder agent and unstashes them on a separate deployer agent.

Example · groovy
stage('Build') {
  agent { label 'builder' }
  steps {
    sh 'npm ci && npm run build'
    stash name: 'compiled', includes: 'dist/**,package.json'
  }
}
stage('Deploy') {
  agent { label 'deployer' }
  steps {
    unstash 'compiled'
    sh 'npm run deploy'
  }
}

Archive only essential artifacts

Archives only the production JAR and its checksum, avoiding the disk cost of archiving the full Maven target directory.

Example · groovy
post {
  success {
    // Archive only the JAR and checksum — not the full target/
    sh 'sha256sum target/myapp.jar > target/myapp.jar.sha256'
    archiveArtifacts artifacts: 'target/myapp.jar,target/myapp.jar.sha256',
                     fingerprint: true
  }
}

Discussion

  • Be the first to comment on this lesson.