Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

4.2.2. Downloading and Managing Artifacts

💡 First Principle: An artifact is an addressable object with a name, a size, an expiry, and a download URL — which means it can be consumed by a later job, by a human, or by a script, and can be deleted the moment it stops earning its storage cost.

Within a run, actions/download-artifact is the consumer side of the handoff from 2.3.2. Version 4 added the patterns that matter for matrix builds:

- uses: actions/download-artifact@v4
  with:
    pattern: build-*        # every artifact whose name matches
    merge-multiple: true    # flatten them into one directory
    path: ./dist

Omitting name entirely downloads all artifacts from the run into per-artifact subdirectories. Downloading from a different run — including in another repository — requires github-token, run-id, and (cross-repo) repository inputs, since the default token is scoped to the current repository.

Outside a run, the UI lists artifacts on the run summary page with a download link and a delete button; the API adds GET .../artifacts/{artifact_id}/zip for the bytes and DELETE .../artifacts/{artifact_id} for cleanup. Retention shows as an expiry date, after which the artifact is removed automatically and the download link 404s. Storage counts toward the account's Actions storage quota, which is why the standard cost-hygiene answer combines short retention-days on noisy artifacts with a scheduled cleanup workflow calling the delete endpoint.

Two constraints round it out: artifacts in v4 are immutable — the same name cannot be uploaded twice in one run (hence build-${{ matrix.os }} naming) — and they are available for download as soon as the upload step completes, not only after the run finishes, which is what makes cross-job consumption fast.

⚠️ Exam Trap: actions/download-artifact defaults to the current run. Fetching an artifact produced by an earlier run or another repository requires explicit run-id, github-token, and repository inputs — a needs: relationship alone does not reach across runs.

Reflection Question: A nightly job must publish the binary built by the most recent successful main CI run. Why can't download-artifact do this with defaults, and what three inputs make it work?

See how it connects
Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications