GitHub Actions Artifacts
Artifacts are files produced by a workflow that you want to keep after the runner shuts down. Since every runner starts clean and disappears after the job ends, any files created during the workflow would normally be lost. Artifacts solve this by saving those files to GitHub's storage, where you can download them or use them in other jobs.
Why Artifacts Matter
Imagine a factory assembly line. Station 1 machines a part. Station 2 inspects it. Station 3 packages it. Each station hands the part to the next one. Without a conveyor belt, the part disappears after each station. Artifacts act as the conveyor belt between jobs.
Job 1: Build
└── Produces: app.zip
↓ (uploaded as artifact)
Job 2: Test
└── Downloads: app.zip
↓ (uses the built app for testing)
Job 3: Deploy
└── Downloads: app.zip
↓ (deploys the exact same build)
Uploading an Artifact
Use the actions/upload-artifact action to save files at the end of a job:
steps:
- name: Build the application
run: npm run build
- name: Upload build output
uses: actions/upload-artifact@v4
with:
name: production-build ← Name for this artifact
path: ./dist ← Folder or file to upload
retention-days: 7 ← Auto-delete after 7 days
The name field identifies the artifact. Use a clear, descriptive name — you reference it by this name when downloading. The path field points to the file or folder on the runner you want to save.
Downloading an Artifact
Use the actions/download-artifact action in a later job to retrieve the saved files:
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: production-build
path: ./dist
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: production-build
path: ./dist ← Where to place the downloaded files
- name: Deploy the app
run: ./deploy.sh ./dist
The deploy job downloads the exact files that build produced. Both jobs run on separate runners, and artifacts are the bridge between them.
Uploading Multiple Files
Upload multiple paths in one step using glob patterns:
- uses: actions/upload-artifact@v4
with:
name: test-results
path: |
reports/coverage/
reports/junit.xml
logs/test.log
The pipe | lets you list multiple paths on separate lines. All files are bundled into one artifact with the given name.
Artifact Retention
GitHub stores artifacts for 90 days by default. After that, they are deleted automatically. You can set a custom retention period using retention-days:
- uses: actions/upload-artifact@v4
with:
name: nightly-report
path: ./reports
retention-days: 30
Keep retention periods short for large artifacts to avoid consuming excessive storage. Test reports and build logs typically need only a few days.
Downloading Artifacts Manually
Anyone with read access to the repository can download artifacts from the GitHub Actions UI:
- Go to the repository on GitHub
- Click the Actions tab
- Click the specific workflow run
- Scroll to the Artifacts section at the bottom
- Click the artifact name to download it as a zip file
This makes artifacts useful for distributing build outputs, test reports, and release packages to team members and stakeholders.
Common Artifact Use Cases
Artifact Type | Produced by | Used for
-----------------------|--------------------|----------------------------
Compiled binary | Build job | Deploy job, manual download
Test coverage report | Test job | Review by developers
JUnit XML results | Test job | CI dashboard parsing
Log files | Any failing job | Debugging and support
Docker image tar | Build job | Load into deploy job
Android APK | Mobile build job | QA testing or release
Artifact Diagram for a Full CI Pipeline
┌─────────────┐ artifact: app.zip ┌──────────────┐
│ build job │ ─────────────────────────► │ test job │
└─────────────┘ └──────┬───────┘
│ artifact: test-report.xml
▼
┌──────────────┐
│ deploy job │
│ (downloads │
│ app.zip) │
└──────────────┘
Artifact Size Limits
GitHub enforces storage limits on artifacts:
- Individual artifact size limit: 10 GB per artifact
- Total storage included varies by plan (2 GB for free accounts)
- Large artifacts consume storage quota even after the workflow finishes
Compress large output folders before uploading to reduce storage usage. You can run tar -czf output.tar.gz ./dist and upload the tar file instead of the raw folder.
Difference Between Artifacts and Cache
Feature | Artifacts | Cache
-----------------|----------------------------|--------------------------------
Purpose | Share files between jobs | Speed up repeated installs
Persists between | Runs (same and different) | Runs (keyed by hash)
Downloaded by | Other jobs or users | Only the job that needs it
Typical contents | Build outputs, reports | node_modules, pip packages
Covered in | This topic | Topic 14
