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:

  1. Go to the repository on GitHub
  2. Click the Actions tab
  3. Click the specific workflow run
  4. Scroll to the Artifacts section at the bottom
  5. 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

Leave a Comment

Your email address will not be published. Required fields are marked *