Git, CI/CD & GitOpsXLIV · ArtifactsFoundations
What an artifact is — the output of a job, named and stored for later
What you'll learn
- Define an artifact as a named, durable, downloadable output of a CI job
- Identify the two inputs of actions/upload-artifact@v4: name and path
- Trace the artifact store as a per-run store scoped to the workflow run ID and the commit SHA
- Distinguish artifacts from caches and outputs by lifetime, scope, and purpose
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
An artifact is a named, durable, downloadable blob a CI job uploads to the artifact store. The job produces some output that another job in the same workflow, or a human reviewer, will need later, and the artifact is the mechanism that gets the output there. The job, the artifact, the downstream job, and the human form a chain: the commit is the source-of-truth, the artifact is the evidence that the commit produced what the PR claimed it would produce, and the downstream job’s correctness depends on the artifact being present.
The two inputs: name and path
The actions/upload-artifact@v4 step has two inputs that matter
and a third that matters less:
- name: Upload plan
uses: actions/upload-artifact@v4
with:
name: terraform-plan
path: tfplan
retention-days: 30
nameis the handle other jobs and humans use to retrieve the artifact. It must be unique within a run. The convention is lowercase, dash-separated, descriptive of the payload (terraform-plan,sbom-cyclonedx,image-oci,junit-report).pathis a single file or a glob of files to upload. A directory uploads recursively; a single file uploads verbatim. The path is relative to the runner workspace unless absolute.retention-daysis the number of days the artifact store retains the blob. The default is the repository’s policy, often 90 days; production pipelines set this explicitly.
The step produces a single artifact from the file or directory at
path. The job can run multiple upload-artifact steps to
produce multiple artifacts; each must have a distinct name.
flowchart LR
A["Job produces tfplan"] --> B["actions/upload-artifact@v4"]
B --> C["Artifact: terraform-plan"]
C --> D["Same workflow, downstream job"]
C --> E["Human reviewer with workflow read"]
C --> F["Archival pipeline outside the run"]
The storage model
The artifact store is a per-run store. Each workflow run has its
own namespace; the name is the key within that namespace. The
artifact is bound to two identifiers:
- The workflow run ID. The artifact exists for the lifetime
configured by
retention-days, scoped to the run. - The commit SHA. The workflow run is bound to a commit; the artifact is therefore bound to that commit too. A reviewer who downloads the artifact can trace it back to the exact commit that produced it.
The two bindings matter because they are the audit invariant of
the artifact. A human who downloads terraform-plan from a PR
review can answer two questions: “what run produced this?” (the
run ID) and “what code produced this?” (the commit SHA). Without
those bindings, the artifact is a blob without provenance.
Artifacts versus caches versus outputs
The three mechanisms covered in Part XXXVIII-06 have distinct purposes:
- Artifacts are durable, named, downloadable, and auditable. They move build outputs between jobs in the same workflow and make them available to humans.
- Caches are key-addressable, best-effort, and evictable. They store dependency payloads to avoid re-downloading on every run.
- Outputs are structured values passed from one step to the next within a single job. They do not survive the job.
flowchart TB
subgraph AR["Artifact"]
A1["name + path"]
A2["retention-days"]
A3["per-run store"]
end
subgraph CA["Cache"]
C1["key + path"]
C2["best-effort"]
C3["cross-run store"]
end
subgraph OU["Output"]
O1["$GITHUB_OUTPUT"]
O2["per-job"]
O3["structured values"]
end
The decision is binary: if the next step needs the data regardless of the cache state, the data is an artifact. If the next step can re-derive the data cheaply, the data is a cache. If the next step is in the same job and needs a structured value, the data is an output.
Production discipline
- Always set
nameexplicitly. The defaultnameis the step ID; rely on it and a future maintainer renaming the step breaks the downstream download. - Always set
pathexplicitly. A glob that matches nothing is a silent failure; theif-no-files-foundinput surfaces it. - Always set
retention-daysexplicitly. The default is per-vendor policy; the production rule is the audit window the team needs. - Treat the artifact as the audit trail. If the artifact must survive the run, the retention is the audit window.
Cross-course references
- Git, CI/CD & GitOps — Part XXXVIII-06 (Artifacts, caches, and outputs) covers the three-mechanism model in detail.
- Terraform for Production Sysadmins — Parts IX-XII (State) applies the same durable-store pattern to Terraform plan storage.
- Linux for Production Sysadmins — Part XXXIV (ConfigMgmt) applies the same model to package builds.
Quiz
Knowledge check · 4 questions
Q1. What are the two required inputs of actions/upload-artifact@v4?
Q2. An artifact is stored in a per-repository store shared across all runs of the workflow.
Q3. Name the three mechanisms for moving data through a CI job and state which one is the audit trail of a CI run.
Q4. A team wants to keep evidence of every CI run for a year. Identify the artifact configuration that satisfies this requirement and the configuration that fails it.
Team T runs a Terraform plan-and-apply pipeline on every PR. The team wants to keep every plan for a year for audit purposes. The current workflow uses actions/upload-artifact@v4 with `name: terraform-plan` and `path: tfplan` and no retention-days. The vendor default retention is 90 days. The team has been retaining plans for one quarter, not one year.
Passing score: 75%. Answers are checked in this browser.