Chapter 14Lesson 01~120 minutes

Artifacts, stash/unstash, archiveArtifacts, Fingerprints, Test Reports, Coverage, and Build Evidence: Concepts, Architecture, and Mental Model

Separate ephemeral workspace output, same-run stash transfer, retained artifacts, fingerprints, typed test/coverage reports, and external repositories so every result stays attributable to its producing build and source revision.

Artifactsstash / unstashFingerprintsJUnitCoverageEvidence

Learning objectives

  • Explain the different lifetimes and ownership boundaries of workspace files, stashes, archived artifacts, fingerprints, reports, and external repositories.
  • Tie every retained file or report to producer job, build number/URL, exact source SHA, artifact path, and digest.
  • Explain why Jenkins fingerprints support usage/dependency tracing but do not provide cryptographic authenticity or supply-chain provenance.
  • Choose between temporary transfer, Jenkins archival, typed report ingestion, and external artifact storage based on lifecycle and scale.
  • Inspect retained evidence without relying on an agent workspace that may already have disappeared.

1. The practical problem: a green build is not an evidence strategy

Earlier chapters separated controller state, Pipeline state, agent workspaces, and external side effects. This chapter adds another boundary: build evidence. A compiler may create a ZIP in an agent workspace, a test tool may write XML, and a coverage tool may create a report, but those files are not automatically durable just because a stage succeeded.

Operators need to answer concrete questions later: Which source revision produced this binary? Which build archived it? What digest did that build record? Which test report was ingested? Was the file merely passed to a later stage, or retained after the run? Did a downstream consumer use the exact same bytes? Those questions require different Jenkins mechanisms.

Evidence rule: workspace existence is execution state; stash is same-run transfer state; archive is build-retention state; a fingerprint is a Jenkins usage-tracking record; a typed report is parsed evidence; an external repository is a separate durable system. Do not collapse them into “the artifact.”

2. Mental model: output → transfer/retention decision → evidence

An agent first creates files in a workspace. From there you choose the lifecycle deliberately. A small file needed later in the same Pipeline run can be stashed and later unstashed into another workspace. A file that must remain attached to the build can be archived. A test or coverage XML file can be parsed into a typed Jenkins report. A file can additionally be fingerprinted so Jenkins can correlate production and use across builds. Long-lived release binaries usually belong in a repository manager rather than in Jenkins alone.

Build-output evidence lifecycle
flowchart TD
 A[Exact SCM revision] --> B[Build on agent workspace]
 B --> C[Output file + SHA-256]
 C --> D{What lifecycle is required?}
 D -->|same run transfer| E[stash]
 E --> F[unstash on another workspace]
 D -->|retain with build| G[archiveArtifacts]
 G --> H[Build artifact record]
 G --> I[Jenkins fingerprint record]
 C --> J[JUnit / coverage XML]
 J --> K[Typed report ingestion]
 C --> L[External artifact repository]
 H --> M[Producer job + build + source SHA]
 I --> M
 K --> M
 L --> N[External coordinates + digest + repository evidence]

The arrows are causal, not decorative. The source revision identifies what was built; the workspace produces bytes; Jenkins either transfers, archives, parses, or fingerprints evidence; external publication has its own acceptance state and must be verified separately.

3. Define the states before changing them

State What it means What proves it What it does not prove
Workspace file Bytes currently exist on an agent filesystem Path, size, digest, node/workspace Retention after cleanup or agent loss
Stash Named file set available later in the same Pipeline run Stash name + successful unstash Long-term release storage
Archived artifact File retained as part of a build record Build artifact UI/API + digest External publication or authenticity
Fingerprint Jenkins record connecting a file checksum to producer/consumer builds Fingerprint page / build relationship Cryptographic provenance or tamper-proof signing
JUnit report Structured test result ingested by Jenkins Test count/failures/history tied to build That the underlying binary is safe to release
Coverage report Structured coverage metrics parsed by a maintained plugin Coverage result + parser/report metadata Test quality or absence of defects
External artifact Artifact accepted by a repository manager Repository coordinates/version/digest Target deployment health

4. stash/unstash: temporary transfer, not a release store

The Pipeline: Basic Steps documentation defines stash as a way to save files for later use on another node or workspace in the same Pipeline run. By default, stashes are deleted when the run completes. Declarative preserveStashes can retain a bounded number of completed-run stashes specifically for restart-from-stage use, but that still does not turn stash into a general artifact repository.

Stash also has a performance boundary. Files are packaged for transfer; large payloads can consume significant controller resources unless an external Artifact Manager redirects the data path. For large or release-critical objects, prefer a proper artifact repository or purpose-built transfer mechanism.

stage('Package') {
  node('lab-linux-a') {
    sh 'tar -czf out/app.tgz app/'
    stash name: 'package-for-test', includes: 'out/app.tgz'
  }
}
stage('Verify elsewhere') {
  node('lab-linux-b') {
    deleteDir()
    unstash 'package-for-test'
    sh 'sha256sum out/app.tgz'
  }
}

5. archiveArtifacts: retain bytes with the producing build

archiveArtifacts copies matching workspace files into the configured Jenkins artifact manager and associates them with the build. The default artifact manager stores them under controller-managed build state; an installed external Artifact Manager can transparently move storage elsewhere. Either way, the build is the logical owner.

archiveArtifacts artifacts: 'out/*.tgz,out/SHA256SUMS', fingerprint: true

Archive only intended outputs. A broad pattern such as **/* can capture source trees, caches, secret files, debug dumps, or enormous directories. Treat the include/exclude pattern as a data-classification boundary.

6. Fingerprints: relationship tracking, not authenticity

Jenkins fingerprints use an MD5 checksum as a lookup key to track where files were produced and consumed. This is valuable for answering “which build used the file produced by build 42?” It is not a modern authenticity or integrity guarantee. MD5 is not appropriate as a cryptographic provenance mechanism.

For integrity evidence, also calculate a modern digest such as SHA-256 and archive the checksum manifest. For stronger supply-chain provenance, use signatures/attestations and repository-side immutable coordinates in later release workflows. Keep the Jenkins fingerprint because it solves a different problem: build relationship discovery.

7. Typed reports are more useful than raw XML alone

A raw reports/junit.xml file is inspectable evidence, but the JUnit plugin parses it into test-case state, counts, trends, and build annotations. Coverage behaves similarly: a maintained Coverage plugin can parse supported formats and create coverage metrics and quality gates. Parsing is a separate state from file creation—“the XML exists” does not prove “Jenkins ingested it.”

Raw file evidence

Path, size, digest, report schema/tool version.

Ingestion evidence

Jenkins build page, parsed test/coverage counts, step log, plugin version.

Source evidence

Repository URL, exact commit SHA, Jenkinsfile revision.

Producer evidence

Job full name, build number/URL, node, workspace, artifact path.

8. Retention is part of architecture

Retaining every artifact, log, source file, and report forever turns Jenkins storage into an unbounded operational liability. Conversely, deleting evidence too aggressively can make incidents or audits impossible to reconstruct. Choose retention by evidence class: short-lived transfer data, CI diagnostics, release candidates, release artifacts, and compliance records have different lifetimes.

When release retention exceeds what Jenkins should own, publish the exact already-verified bytes to an external repository and retain the external coordinates and digest in Jenkins. Promotion should move or reclassify those same bytes, not silently rebuild from the branch name.

9. Read-only inspection checklist

  • Record job full name, build number/URL, exact source SHA and Jenkinsfile revision.
  • Record agent/node label, workspace path, artifact filename/path, size and SHA-256.
  • List configured build retention before assuming an artifact will remain forever.
  • Inspect stash names only as same-run transfer evidence; do not treat them as external release coordinates.
  • Record JUnit and Coverage plugin versions before interpreting typed results.
  • Inspect fingerprint relationships, but label them correctly as Jenkins dependency tracking.
  • If an external repository is involved, verify its coordinates and digest independently from Jenkins.

10. Common wrong approaches

Wrong approach Why it fails Safer pattern
“The file is still in the workspace.” Workspace can be deleted, re-used, or lost with an ephemeral agent. Archive or publish deliberately.
Use stash for release binaries Stash is run-scoped and optimized for transfer, not release lifecycle. Archive for build retention; repository manager for releases.
Fingerprint means secure hash Fingerprint is MD5-based relationship tracking. Add SHA-256/signatures/provenance for integrity/authenticity.
Archive all workspace files Can leak secrets and waste storage. Narrow allowlisted patterns + sensitivity review.
Rebuild when promoting Creates different bytes from the verified build. Promote the exact artifact/digest already produced.
Next lesson

Guided Hands-On Workflow and Core Operations

Build one synthetic artifact, move it across workspaces, archive and fingerprint it, ingest JUnit evidence, optionally ingest coverage, then delete workspace state and prove what remains.

Knowledge check

What is the defining lifetime of a normal stash?

What does archiveArtifacts prove?

Why is a Jenkins fingerprint not a supply-chain signature?

What is the difference between a JUnit XML file existing and Jenkins showing test results?

Why should release promotion avoid rebuilding?

Official references and version notes

Version and compatibility note

Rechecked on 2026-09-16. Examples assume Jenkins 2.568.3 LTS (tested with Java 21 and 25), Pipeline: Basic Steps 1098.v808b_fd7f8cf4, Pipeline: Job 1600.v6f36ed83529d, and JUnit 1425.v9c7318dca_96d. The optional coverage extension uses Coverage 3.3358.v9487dde48783, which requires Jenkins 2.555.3 or newer and is therefore compatible with this LTS baseline. The mandatory path is free/local/disposable. Record the versions actually installed on your controller before applying the examples.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.