GitHub Actions Cheatsheet

Artifacts

Use this GitHub Actions reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Upload an Artifact

- uses: actions/upload-artifact@v4
  with:
    name: build-output          # artifact name
    path: dist/                 # file, dir, or glob
    retention-days: 7           # default: 90, max: 90 (or org policy)
    if-no-files-found: error    # error | warn | ignore (default: warn)
    compression-level: 6        # 0 (none) – 9 (max), default 6
    overwrite: true             # replace if name already exists

Download an Artifact

- uses: actions/download-artifact@v4
  with:
    name: build-output          # omit to download ALL artifacts
    path: ./downloaded           # destination (default: workspace root)
    merge-multiple: true         # merge multiple artifacts into path

Cross-Job Artifact Sharing

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: npm run build

      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

  test:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/

      - run: ls dist/ && npm run test:e2e

Upload Multiple Artifacts

# Upload with separate names
- uses: actions/upload-artifact@v4
  with:
    name: linux-binary
    path: build/app-linux

- uses: actions/upload-artifact@v4
  with:
    name: windows-binary
    path: build/app-windows.exe

# Upload a glob (all matched files into one artifact)
- uses: actions/upload-artifact@v4
  with:
    name: test-results
    path: |
      coverage/
      test-results/**/*.xml
      !test-results/**/temp/

Download All Artifacts

- uses: actions/download-artifact@v4
  # No 'name' = downloads all artifacts
  # Each artifact lands in a subdirectory named after it
  with:
    path: artifacts/

- run: ls artifacts/
# artifacts/
#   linux-binary/
#   windows-binary/
#   test-results/

Matrix Artifact Pattern

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - run: make build
      - uses: actions/upload-artifact@v4
        with:
          name: binary-${{ matrix.os }}
          path: bin/

  release:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: binaries/
          merge-multiple: false   # keep per-artifact subdirectories

      - run: ls binaries/

Artifact Retention

# Keep test results for 30 days
- uses: actions/upload-artifact@v4
  with:
    name: test-reports
    path: reports/
    retention-days: 30

# Keep coverage reports longer
- uses: actions/upload-artifact@v4
  with:
    name: coverage
    path: coverage/
    retention-days: 90

# Only keep on failure
- if: failure()
  uses: actions/upload-artifact@v4
  with:
    name: debug-logs
    path: logs/
    retention-days: 5

Artifacts vs Cache

FeatureArtifactsCache
PurposeShare build outputs between jobs / download externallySpeed up builds by reusing files
Persists after runYes (retention-days)7 days since last access
Cross-job sharingYes (needs: not required — any job can download)Yes
Cross-run sharingNoYes
Max size10 GB per artifact10 GB per repo total
CLI downloadgh run downloadNot directly

Download Artifacts via CLI

# Download from a specific run
gh run download <run-id>
gh run download <run-id> --name build-output
gh run download <run-id> --dir ./artifacts

# Download from the latest run
gh run download --name dist

# List artifacts for a run
gh api repos/OWNER/REPO/actions/runs/RUN_ID/artifacts \
  --jq '.artifacts[] | {name: .name, size: .size_in_bytes, url: .archive_download_url}'

Upload Test Results as Annotations

- run: npm test -- --reporter=junit --output-file=test-results.xml
  continue-on-error: true

- uses: mikepenz/action-junit-report@v4
  if: always()
  with:
    report_paths: test-results.xml
    github_token: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/upload-artifact@v4
  if: always()
  with:
    name: junit-results
    path: test-results.xml

Artifact Limits

PropertyLimit
Max artifact size10 GB
Default retention90 days
Max retention90 days (public); org-configured for private
Concurrent uploads64 per run
Individual file size in artifactNo explicit limit (up to artifact max)