Artifacts, Workspaces, and Cross-Step State
CI state disappears at boundaries unless you persist it deliberately. Reliable pipelines distinguish short-lived workspace files, cross-step metadata, build artifacts, caches, and durable operational state.
Learning objectives
By the end of this lesson
- Distinguish step, job, and workflow state lifetimes.
- Publish artifacts instead of relying on local runner files.
- Treat caches as disposable optimization.
- Attach checksums and provenance to build outputs.
- Keep durable deployment truth outside ephemeral workspaces.
1. Steps, jobs, and workflows have different state lifetimes
Always consult your CI platform for exact semantics, but design as if process state disappears at every step boundary.
2. Workspace files are ordinary files, not guaranteed durable artifacts
build_dir=${CI_WORKSPACE:-"$PWD"}/build
mkdir -p -- "$build_dir"
printf 'binary\n' > "$build_dir/app.bin"The workspace is convenient within a job, but later jobs may run on another machine.
3. Persist small cross-step values explicitly
artifact_id='artifact-123'
printf 'artifact_id=%s\n' "$artifact_id" \
>> "$CI_OUTPUT_FILE"Each CI system has its own supported output mechanism. Use it for small metadata rather than relying on environment mutation in one shell process to affect another.
4. Environment files need escaping and schema rules
cat > build.env <<EOF
ARTIFACT_ID=$artifact_id
VERSION=$version
EOFSimple KEY=value files become fragile when values contain newlines, shell syntax, or untrusted text. Use a structured format when values are not constrained.
5. Build artifacts should be immutable outputs of a job
tar -czf release.tar.gz -C build .
sha256sum release.tar.gz > release.tar.gz.sha256Publish the artifact and checksum through the CI platform's artifact mechanism so downstream jobs consume the exact build result.
6. Cache is an optimization, not authoritative state
Dependency caches can speed builds, but a cache miss should not make a correct pipeline fail. A cache hit should not silently change what source revision or declared dependency versions mean.
Artifacts are workflow outputs; caches are disposable performance accelerators.
7. Give artifacts stable identity
version=${VERSION:?}
commit=${COMMIT_SHA:?}
name="myapp-${version}-${commit}.tar.gz"
printf 'artifact_name=%s\n' "$name"A name that includes version or commit identity helps trace an artifact back to source.
8. Store machine-readable metadata beside the artifact
jq -n \
--arg version "$version" \
--arg commit "$commit" \
--arg created "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
'{
version: $version,
commit: $commit,
created: $created
}' > release-metadata.jsonThis avoids scraping filenames later to recover important provenance.
9. Downstream jobs should validate downloaded artifacts
sha256sum -c release.tar.gz.sha256
tar -tzf release.tar.gz >/dev/nullDo not assume a transferred artifact is valid merely because the CI platform delivered a file.
10. Durable deployment state belongs outside ephemeral workspaces
If later workflow runs must know which version is deployed, store that truth in the deployment system, release registry, artifact repository, Git tag, database, or another durable source rather than a leftover runner file.
11. Cleanup temporary workspace state without deleting required artifacts
tmpdir=$(mktemp -d) || exit 1
trap 'rm -rf -- "$tmpdir"' EXIT
# Final artifact is written outside tmpdir:
cp -- "$tmpdir/output.tar.gz" ./release.tar.gzSeparate scratch paths from outputs that the CI platform still needs to upload after your script finishes.
12. Hands-on lab: build an artifact with provenance
mkdir -p "$HOME/devops-academy/bash/chapter16/lesson03"
cd "$HOME/devops-academy/bash/chapter16/lesson03"
mkdir -p build
printf 'hello release\n' > build/app.txt
version=1.2.0
commit=demo1234
artifact="myapp-${version}-${commit}.tar.gz"
tar -czf "$artifact" -C build .
sha256sum "$artifact" > "$artifact.sha256"
cat > metadata.json <<EOF
{
"version": "$version",
"commit": "$commit",
"artifact": "$artifact"
}
EOF
sha256sum -c "$artifact.sha256"
tar -tzf "$artifact"
cat metadata.jsonVerification checklist
13. Knowledge check
Question 1. Why don't ordinary shell variables normally survive across CI steps?
Question 2. What is the difference between an artifact and a cache?
Question 3. Where should durable deployment truth live?
Question 4. Why verify artifacts after transfer?
14. Summary
CI state has explicit lifetimes. Keep small cross-step values in supported output channels, publish build results as artifacts, treat caches as disposable, attach provenance and checksums, and store durable operational truth outside ephemeral runner filesystems.
15. Further reading
- GNU Coreutils checksum utilities.
- tar documentation.
- jq manual for artifact metadata.
- Your CI platform's documentation for workspaces, artifacts, caches, and step/job outputs.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.