Artifacts & Releases
Artifacts#
Standard artifacts: keywords (paths, exclude, reports, needs, dependencies, when, expire_in) work the same as production GitLab CI. This page covers glci-specific behavior and differences.
How artifacts work in glci#
- A job finishes and the runner uploads its
artifacts: paths:as a zip archive to the mock server. - The mock server holds the artifact in memory (or on a mounted volume for persistent mock containers).
- Downstream jobs that declare
needs:ordependencies:on the upstream job automatically receive the artifact zip, which the runner extracts into the build directory before running the job’s script.
The mock server enforces a 1 GB maximum per artifact upload. There is no configurable override.
artifacts: reports: entries (junit, cobertura, sast, etc.) are passed through to the runner but glci does not render or aggregate them. The raw report files are included in the artifact archive and can be inspected via glci artifacts inspect or glci artifacts extract.
Exception: artifacts: reports: dotenv is fully supported. When a job uploads a dotenv report, glci extracts the KEY=VALUE pairs and injects them as variables into downstream jobs that declare needs: or dependencies: on the producer — matching GitLab CI behavior. When neither needs: nor dependencies: is specified, dotenv variables propagate from all jobs in prior stages (the default dependency behavior).
Limits: a dotenv artifact may contain at most 20 variables (matching GitLab’s default). The decompressed file must be under 5 MB. Variables beyond the limit are silently dropped. Keys must match [a-zA-Z_][a-zA-Z0-9_]*; lines with invalid keys or format are skipped.
producer:
script: echo "MY_VAR=hello" > variables.env
artifacts:
reports:
dotenv: variables.env
consumer:
needs: [producer]
script: echo $MY_VAR # prints "hello"
Reusing artifacts across runs#
When iterating on a failing job, skip re-running upstream dependencies if their artifacts already exist from a prior pipeline:
glci run --reuse-artifacts test-integration
CLI commands#
List:
glci artifacts list # from latest pipeline
glci artifacts list 38 # from a specific pipeline
glci artifacts list --all # across all pipelines
Download and extract:
glci artifacts download build # latest pipeline
glci artifacts download 38 build --output /tmp/b.zip # specific pipeline
glci artifacts extract build # to ./build/
glci artifacts extract 38 build --output /tmp/build/ # specific dir
Inspect and compare:
glci artifacts inspect build # list zip contents without extracting
glci artifacts diff 41 42 --job build # compare between two pipelines
Delete:
glci artifacts delete 38 # all from pipeline #38
glci artifacts delete 38 build # specific job artifact
glci artifacts delete --all # all from all pipelines
glci artifacts delete --older-than 7d # older than 7 days
Pipeline ID is optional for download, extract, and inspect – defaults to the latest pipeline that has artifacts for the named job.
Releases#
The release: keyword works the same as production GitLab CI. glci generates a release step appended to the job’s script (after main script, before after_script). The generated step:
- Checks for
glab>= 1.58.0 in the container. - If found, authenticates via
glab auth login --job-token $CI_JOB_TOKENand runsglab release create. - If
glabis unavailable or too old, falls back torelease-cli create(with a deprecation warning:release-cliwill not be supported after GitLab 20.0).
Release creation goes to the embedded mock server, not the real GitLab API. The release is stored locally and can be browsed via glci releases.
All release: fields are supported: tag_name, name, description, tag_message, ref, milestones, released_at, and assets: links: (with name, url, link_type).
CI_RELEASE_DESCRIPTION is set with raw=true (so $-references are not expanded) and truncated to 1024 characters, matching GitLab’s behavior.
CLI commands#
glci releases list # from latest pipeline
glci releases list --all # across all pipelines
glci releases show v1.2.3 # show release details
glci releases download v1.2.3 # download all package files
glci releases download v1.2.3 my-app.tar.gz # download single file
Running release jobs locally#
Standard release: YAML works as-is. Use a tag context to set CI_COMMIT_TAG:
glci run --context tag=v1.2.3 release-job
Troubleshooting#
Artifacts not found by downstream jobs#
- Incorrect
needs:reference: The job name must exactly match (including matrix suffixes). Check withglci show. artifacts: falseon the need: Downstream job will not receive file artifacts. Remove or set totrue. Note:artifacts: falseonly blocks file downloads —artifacts: reports: dotenvvariables still propagate.- Artifact paths don’t match:
artifacts: paths:globs are relative to$CI_PROJECT_DIR.
Artifact upload too large#
The mock server rejects uploads larger than 1 GB. Narrow artifacts: paths: or use artifacts: exclude:.
Artifacts missing after daemon restart#
Completed pipeline artifacts are persisted in the history store under ~/.glci/projects/. In-flight artifacts in a pipeline container are lost on daemon restart.
Reports artifacts not visible#
glci does not render report artifacts (junit, cobertura, etc.) – use glci artifacts inspect or glci artifacts extract to access the raw files. The exception is artifacts: reports: dotenv, which is fully processed for variable propagation between jobs.