How to Pass Data Between Stages in a Jenkins Pipeline
Jenkins carries values between stages via env, and files between stages or agents via stash/unstash.
Assign to env.NAME (or a script-scoped Groovy variable) to share a value across stages on the same run. To move files across stages or agents, stash then unstash.
Share a value and a file
The build stage sets an env value and stashes the artifact; the deploy stage reads both.
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
env.APP_VERSION = sh(script: 'node -p "require(\'./package.json\').version"', returnStdout: true).trim()
}
sh 'npm ci && npm run build'
stash name: 'dist', includes: 'dist/**'
}
}
stage('Deploy') {
steps {
unstash 'dist'
sh './deploy.sh "$APP_VERSION" dist/'
}
}
}
}Gotchas
- Set
env.NAMEinside ascript {}block for a computed value; a plainenvironment {}entry is evaluated once up front. stash/unstashmove files within a single build across stages/agents - they are not a cross-build cache.- Large stashes are slow; stash only what the downstream stage needs.
Verify it actually works
Validate the pipeline definition against the running controller before committing. Jenkins parses declarative pipelines strictly, and a syntax error surfaces as a failed build rather than a clear parse message.
# validate a Jenkinsfile against the live controller
curl -X POST -F "jenkinsfile=<Jenkinsfile" \
https://your-jenkins/pipeline-model-converter/validate
# replay a build with modified script to test a change without committing
# Build page -> Replay -> edit -> RunAgent and workspace assumptions that break in CI
- An agent label that matches no online agent leaves the build queued indefinitely rather than failing.
- Workspaces are reused between builds by default, so stale files from a previous run can mask or cause failures. Use
cleanWs()or a fresh workspace when correctness matters. - Tools resolved from the controller PATH are not necessarily on the agent PATH. Declare them in a
toolsblock or install them in the pipeline. - Credentials bound with
withCredentialsare masked in logs but still visible to any process you launch; avoid passing them as command-line arguments.