Storing Artifacts
Learn how to store and share build artifacts in GitHub Actions
Storing Artifacts
Artifacts in GitHub Actions allow you to persist data after a job completes and share data between jobs in the same workflow. This is essential for saving build outputs, test reports, and other important files.
What are Artifacts?
Artifacts are files or collections of files that you want to save and share:
- Build outputs: Compiled binaries, packages
- Test results: Coverage reports, test logs
- Documentation: Generated docs, reports
- Deployment packages: Docker images, release files
Basic Usage
Upload Artifacts
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build application
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-files
path: dist/
Download Artifacts
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Build app
run: npm run build
- uses: actions/upload-artifact@v3
with:
name: app-build
path: dist/
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: app-build
path: ./dist
- name: Deploy
run: ./deploy.sh
Advanced Artifact Usage
Multiple Artifacts
- name: Upload multiple artifacts
uses: actions/upload-artifact@v3
with:
name: test-results
path: |
coverage/
test-reports/
logs/*.log
Conditional Uploads
- name: Upload on failure
if: failure()
uses: actions/upload-artifact@v3
with:
name: failure-logs
path: logs/
Artifact Retention
- name: Upload with custom retention
uses: actions/upload-artifact@v3
with:
name: build-outputs
path: dist/
retention-days: 30 # Default is 90 days
Common Patterns
Build Matrix Artifacts
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Build
run: npm run build
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: build-${{ matrix.os }}
path: dist/
Test Reports
- name: Run tests
run: npm test -- --coverage --outputFile=test-results.xml
- name: Upload test results
if: always() # Upload even if tests fail
uses: actions/upload-artifact@v3
with:
name: test-results
path: |
coverage/
test-results.xml
Docker Images
- name: Build Docker image
run: |
docker build -t myapp .
docker save myapp > myapp.tar
- name: Upload Docker image
uses: actions/upload-artifact@v3
with:
name: docker-image
path: myapp.tar
Cross-Job Communication
Share Data Between Jobs
jobs:
prepare:
runs-on: ubuntu-latest
steps:
- name: Generate config
run: echo "config data" > config.json
- name: Upload config
uses: actions/upload-artifact@v3
with:
name: config
path: config.json
process:
needs: prepare
runs-on: ubuntu-latest
steps:
- name: Download config
uses: actions/download-artifact@v3
with:
name: config
- name: Use config
run: cat config.json
Multiple Downloads
- name: Download all artifacts
uses: actions/download-artifact@v3
- name: Download specific artifact
uses: actions/download-artifact@v3
with:
name: specific-artifact
path: ./downloads
Best Practices
Naming Conventions
# Good: Descriptive names
name: build-${{ github.sha }}-${{ matrix.os }}
name: test-results-${{ github.run_number }}
name: coverage-report-${{ github.ref_name }}
# Include metadata in names
name: app-v${{ steps.version.outputs.version }}-linux
Size Management
# Compress large artifacts
- name: Compress artifacts
run: tar -czf logs.tar.gz logs/
- name: Upload compressed logs
uses: actions/upload-artifact@v3
with:
name: logs-compressed
path: logs.tar.gz
Exclude Unnecessary Files
- name: Upload selective files
uses: actions/upload-artifact@v3
with:
name: build-output
path: |
dist/
!dist/**/*.map
!dist/**/test-*
Security Considerations
Sensitive Data
# DON'T upload sensitive information
# Artifacts are accessible to anyone with read access
# DO filter out sensitive files
- name: Clean sensitive data
run: |
rm -f .env
rm -f config/secrets.json
- name: Upload clean build
uses: actions/upload-artifact@v3
with:
name: clean-build
path: dist/
Access Control
# Artifacts inherit repository permissions
# Private repos: Only collaborators can access
# Public repos: Anyone can download artifacts
Troubleshooting
Common Issues
# Issue: Artifact not found
# Solution: Check artifact name and job dependencies
# Issue: Path not found
# Solution: Verify file paths exist
- name: Debug paths
run: |
ls -la
find . -name "*.log" -type f
# Issue: Size limits exceeded
# Solution: Compress or split artifacts
- name: Check artifact size
run: du -sh dist/
Debugging Downloads
- name: Debug artifact download
uses: actions/download-artifact@v3
with:
name: my-artifact
- name: List downloaded files
run: |
ls -la
find . -type f -name "*"
Complete Examples
Build and Test Pipeline
name: Build and Test
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-${{ github.sha }}
path: dist/
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: test-results-${{ github.sha }}
path: |
coverage/
test-results.xml
deploy:
if: github.ref == 'refs/heads/main'
needs: [build, test]
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: build-${{ github.sha }}
path: ./dist
- name: Deploy to staging
run: |
echo "Deploying files:"
ls -la dist/
Multi-Platform Build
name: Multi-Platform Build
on: [push]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: ubuntu-latest
artifact-name: linux
- os: windows-latest
artifact-name: windows
- os: macos-latest
artifact-name: macos
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Build application
run: npm run build
- name: Upload platform artifacts
uses: actions/upload-artifact@v3
with:
name: app-${{ matrix.artifact-name }}
path: dist/
package:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v3
- name: Package release
run: |
mkdir release
cp -r app-linux/ release/
cp -r app-windows/ release/
cp -r app-macos/ release/
tar -czf release.tar.gz release/
- name: Upload release package
uses: actions/upload-artifact@v3
with:
name: release-package
path: release.tar.gz