GitLab CI/CD Specialist study materials
GitLab CI/CD Specialist study resources

GitLab CI/CD Specialist practice questions

One question at a time. Build your GitLab CI/CD Specialist understanding.

First 50 of 200 questions. Each one lists the choices, the correct answer, and an explanation. The checker at the top of this page saves progress in this browser when it is available.

Continue in the practice tool above to load more questions, 50 at a time.

Question 1Pipeline configuration and authoring

In a .gitlab-ci.yml file, which top-level keyword is used to declare named stages and define their execution order?

  1. sequence
  2. stages Correct answer.
  3. stage
  4. pipeline

Explanation

The top-level stages keyword lists stage names in the order jobs should run; jobs then reference one of those names with their job-level stage keyword. Jobs in the same stage run in parallel, and the next stage begins only after the previous one succeeds.

Question 2Pipeline configuration and authoring

A job must run only when the pipeline is triggered by a merge request event. Which job-level keyword controls this?

  1. rules Correct answer.
  2. resource_group
  3. interruptible
  4. environment

Explanation

The rules keyword evaluates conditions such as the pipeline source and includes or excludes the job accordingly; a rule checking $CI_PIPELINE_SOURCE == "merge_request_event" limits the job to merge request pipelines. rules replaces only/except for this purpose and is evaluated in order, first match winning.

Question 3Pipeline configuration and authoring

Which keyword stores a job artifact so that it can be downloaded from the pipeline page and passed to later jobs?

  1. cache
  2. artifacts Correct answer.
  3. dependencies
  4. needs

Explanation

The artifacts keyword declares files produced by a job that GitLab uploads and makes available for download and for consumption by later jobs. cache is for reusable files between pipeline runs, not for publishing outputs.

Question 4Pipeline configuration and authoring

What does the extends keyword do in a .gitlab-ci.yml file?

  1. Appends additional script lines to the end of the referenced job's script
  2. Creates a new pipeline that inherits the current project's settings
  3. Replaces the current job's configuration with the referenced job's configuration
  4. Merges the configuration of a referenced template or hidden job into the current job Correct answer.

Explanation

extends performs a reverse deep merge: keys from the referenced job or template are merged into the extending job, and the extending job's own keys take precedence. It is commonly used with hidden jobs whose names begin with a dot.

Question 5Pipeline configuration and authoring

Which reserved keyword in a .gitlab-ci.yml file marks a job as a template that is never executed?

  1. hidden job names beginning with a dot Correct answer.
  2. workflow
  3. include
  4. default

Explanation

Jobs whose names start with a dot are hidden jobs: they are not added to the pipeline but can be referenced by extends or anchors. This makes them the standard way to define reusable job templates inside a single file.

Question 6Pipeline configuration and authoring

Which predefined variable identifies the branch or tag ref for the running pipeline?

  1. CI_JOB_TOKEN
  2. CI_COMMIT_SHA
  3. CI_COMMIT_REF_NAME Correct answer.
  4. CI_PIPELINE_ID

Explanation

CI_COMMIT_REF_NAME holds the branch or tag name the pipeline was created for. CI_COMMIT_SHA is the commit hash, CI_PIPELINE_ID is the pipeline's numeric identifier, and CI_JOB_TOKEN is an authentication token.

Question 7Pipeline configuration and authoring

Which keyword is used to run a job's steps inside a specific container image?

  1. tags
  2. before_script
  3. services
  4. image Correct answer.

Explanation

The image keyword specifies the Docker image in which the job's script executes, so the job's toolchain comes from that image. services is used for additional sidecar containers such as databases.

Question 8Pipeline configuration and authoring

Which keyword lets a job start before the previous stage has finished, using artifacts from specific earlier jobs?

  1. needs Correct answer.
  2. parallel
  3. when
  4. allow_failure

Explanation

needs expresses a directed acyclic graph: a job can start as soon as its listed dependencies complete, even if the rest of the earlier stage is still running. This shortens pipelines compared with strict stage ordering.

Question 9Pipeline configuration and authoring

A job must run only on the default branch, and the configuration should use rules. Which rule condition achieves this?

  1. rules: - if: '$CI_COMMIT_TAG != null'
  2. rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' Correct answer.
  3. rules: - if: '$CI_PIPELINE_SOURCE == "schedule"'
  4. rules: - if: '$CI_MERGE_REQUEST_ID'

Explanation

Comparing CI_COMMIT_BRANCH with CI_DEFAULT_BRANCH matches pipelines for the project's default branch. The other conditions target tags, scheduled pipelines, or merge request pipelines instead.

Question 10Pipeline configuration and authoring

A job's script should run only when a variable named DEPLOY_ENV is set to production. Which rules clause expresses this correctly?

  1. rules: - changes: [DEPLOY_ENV]
  2. rules: - if: '$DEPLOY_ENV == "production"' Correct answer.
  3. rules: - when: manual
  4. rules: - exists: [DEPLOY_ENV]

Explanation

A rules if expression can compare a pipeline variable against a literal string, so '$DEPLOY_ENV == "production"' includes the job only when that value is set. changes and exists test file paths, not variable values.

Question 11Pipeline configuration and authoring

Two jobs declare artifacts with the same name, and a later job uses needs on both. What does GitLab do with the artifacts?

  1. The later job downloads artifacts only from the last job in needs
  2. Only the artifact from the job listed first in needs is downloaded
  3. Both artifacts are downloaded and the later one overwrites conflicting files Correct answer.
  4. The pipeline fails because artifact names must be unique across jobs

Explanation

When a job downloads artifacts from multiple jobs, GitLab fetches each artifact archive and later downloads can overwrite files with the same path. Duplicate artifact names do not by themselves fail the pipeline.

Question 12Pipeline configuration and authoring

A job uses parallel: 4 and needs to know which instance it is. Which variable distinguishes the instances?

  1. CI_NODE_INDEX Correct answer.
  2. CI_PIPELINE_IID
  3. CI_CONCURRENT_ID
  4. CI_JOB_ID

Explanation

With parallel, GitLab sets CI_NODE_INDEX to the zero-based index of each parallel instance and CI_NODE_TOTAL to the total count. The other variables identify the job, concurrency slot, or project-scoped pipeline number.

Question 13Pipeline configuration and authoring

A pipeline should be skipped entirely when only documentation files change. Which configuration achieves this?

  1. Set the docs job to when: never
  2. Add only: [docs] to the default section
  3. Use workflow:rules with a rule that excludes changes to docs paths Correct answer.
  4. Add rules with changes to every job in the pipeline

Explanation

workflow:rules decides whether the pipeline is created at all, so a rule that excludes pipelines where only documentation paths changed prevents the whole pipeline from running. Per-job rules would still create a pipeline with other jobs.

Question 14Pipeline configuration and authoring

A job must not run concurrently with another job that deploys to the same target. Which keyword enforces this?

  1. interruptible
  2. retry
  3. resource_group Correct answer.
  4. timeout

Explanation

resource_group ensures that only one job with a given resource group value runs at a time across the project, which prevents concurrent deployments to the same target. Jobs queue until the resource is free.

Question 15Pipeline configuration and authoring

A job script needs a database service available during the test run. Which configuration provides it?

  1. cache: {key: postgres}
  2. variables: {POSTGRES: enabled}
  3. services: [postgres:16] Correct answer.
  4. image: postgres

Explanation

The services keyword starts additional containers linked to the job container, which is how a database such as PostgreSQL is made reachable during tests. The job then connects to the service hostname.

Question 16Pipeline configuration and authoring

Which statement about include is correct when the same keyword is defined both in an included file and in the main .gitlab-ci.yml?

  1. The included file always overrides the main file
  2. Included files are ignored when the main file defines the same key
  3. The main file's value takes precedence over the included file's value Correct answer.
  4. The pipeline fails because duplicate keys are not allowed

Explanation

Includes are merged into the configuration, and values defined in the main .gitlab-ci.yml take precedence over values from included files. This lets a project override defaults supplied by shared templates.

Question 17Pipeline configuration and authoring

A job should be allowed to fail without blocking the pipeline, but only for a specific exit code. Which configuration does this?

  1. allow_failure: true
  2. allow_failure: {exit_codes: [137]} Correct answer.
  3. when: on_failure
  4. retry: {max: 1, when: script_failure}

Explanation

allow_failure accepts a hash with exit_codes so the job is treated as a warning only when it exits with one of the listed codes; other failures still fail the pipeline. Plain allow_failure: true treats any failure as non-blocking.

Question 18Pipeline configuration and authoring

A job must run after a manual action by a user and should not block later stages while waiting. Which keyword setting accomplishes this?

  1. when: always
  2. when: delayed with start_in: 5 minutes
  3. when: manual with allow_failure: true Correct answer.
  4. when: on_success

Explanation

A manual job with allow_failure: true is optional: the pipeline does not wait for it and later stages can proceed. Without allow_failure, a manual job blocks the pipeline until someone runs or skips it.

Question 19Pipeline configuration and authoring

A job defines before_script and the global default also defines before_script. Which runs?

  1. Only the job-level before_script runs Correct answer.
  2. The pipeline fails because before_script is defined twice
  3. Only the global before_script runs
  4. Both run, with the global one first

Explanation

A job-level keyword overrides the value inherited from the global default section rather than merging with it. Therefore the job's own before_script replaces the global one for that job.

Question 20Pipeline configuration and authoring

Which YAML feature is commonly used together with hidden jobs to reuse a block of script lines inside the same file?

  1. YAML tags
  2. YAML anchors and merge keys Correct answer.
  3. Multi-line flow scalars
  4. Document separators

Explanation

Anchors (&name) and merge keys (<<: *name) let a configuration reuse a mapping or list defined elsewhere in the same file, which pairs well with hidden jobs. include and extends are used for reuse across files or jobs.

Question 21Pipeline configuration and authoring

A job uses rules with two entries: the first has if: '$CI_COMMIT_BRANCH' and when: never, the second has when: on_success. What happens on a branch pipeline?

  1. The job runs twice, once per matching rule
  2. The job runs because the second rule matches
  3. The pipeline fails because the rules conflict
  4. The job is excluded because the first matching rule wins Correct answer.

Explanation

rules are evaluated in order and the first matching rule determines the job's behavior; later rules are not considered. Because the first rule matches branch pipelines and sets when: never, the job is excluded there.

Question 22Pipeline configuration and authoring

A job uses needs on a job in the same stage, and that needed job fails. What is the result for the dependent job?

  1. The dependent job runs because needs ignores job status
  2. The dependent job retries the failed job automatically
  3. The dependent job is skipped because a needed job failed Correct answer.
  4. The dependent job runs only if allow_failure is false

Explanation

When a job listed in needs fails, the dependent job cannot run and is skipped, which can cause the pipeline to end early. needs changes ordering but still respects the success of its dependencies.

Question 23Pipeline configuration and authoring

A job sets cache:key: $CI_COMMIT_REF_SLUG and another job in the same pipeline uses the same key. What is the intended effect?

  1. The cache is shared across all branches and pipelines
  2. The cache is scoped per job name and never shared
  3. The cache is invalidated on every pipeline run
  4. The cache is scoped per branch, so jobs on the same branch reuse it Correct answer.

Explanation

Using CI_COMMIT_REF_SLUG in cache:key scopes the cache to the branch or tag, so jobs on the same ref can reuse it while other refs get separate caches. It does not make the cache global or force invalidation each run.

Question 24Pipeline configuration and authoring

A pipeline uses both workflow:rules and job-level rules. A job's rules match, but workflow:rules excludes the pipeline. What happens?

  1. The pipeline is created with only that job
  2. No pipeline is created, so the job never runs Correct answer.
  3. The pipeline fails with a configuration error
  4. The job runs because job rules take precedence over workflow rules

Explanation

workflow:rules decide whether a pipeline is created at all; if they exclude the pipeline, no jobs run regardless of their own rules. Job-level rules only apply once a pipeline exists.

Question 25Pipeline configuration and authoring

A job uses retry with when: [runner_system_failure, stuck_or_timeout_failure] and max: 2. How many total attempts can the job make?

  1. Two attempts total
  2. Unlimited attempts until success
  3. One attempt only
  4. Three attempts total Correct answer.

Explanation

retry:max counts retries after the initial attempt, so max: 2 allows up to three total attempts for the listed failure conditions. Failures not matching the when list are not retried.

Question 26Pipeline configuration and authoring

Which top-level keyword defines the ordered list of stages that jobs may reference in a pipeline?

  1. pipeline
  2. stages Correct answer.
  3. order
  4. stage

Explanation

The stages keyword at the top level of .gitlab-ci.yml declares the ordered sequence of stages; jobs then attach to one of these names with the job-level stage keyword. Jobs whose stage is not declared are rejected by the pipeline linter, and the declared order determines the default sequencing of jobs.

Question 27Pipeline configuration and authoring

A job must always run regardless of the outcome of earlier stages, for example to publish a report. Which job-level keyword value accomplishes this?

  1. when: manual
  2. when: always Correct answer.
  3. when: on_success
  4. when: delayed

Explanation

when: always makes the job run whether preceding stages succeeded or failed, which suits reporting or cleanup tasks. The default when: on_success runs only after prior stages pass, so it would skip the job exactly when the report matters most.

Question 28Pipeline configuration and authoring

Which keyword references a file from another project so its contents can be merged into the current pipeline configuration?

  1. include:project Correct answer.
  2. include:template
  3. include:remote
  4. include:local

Explanation

include:project pulls a configuration file from another GitLab project, combined with ref and file to identify the revision and path. The other include variants read from the same repository, from GitLab-provided templates, or from a public URL rather than a separate project.

Question 29Pipeline configuration and authoring

A job should only be created when a Git tag matching a pattern is pushed. Which rules clause expresses this?

  1. if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+$/' Correct answer.
  2. if: '$CI_PIPELINE_SOURCE == "push"'
  3. if: '$CI_COMMIT_BRANCH =~ /^v\d+\.\d+$/'
  4. if: '$CI_COMMIT_REF_NAME'

Explanation

For tag pipelines, CI_COMMIT_TAG holds the tag name while CI_COMMIT_BRANCH is empty, so matching CI_COMMIT_TAG against a regular expression restricts the job to matching tags. The regex operator =~ with a slash-delimited pattern is the supported syntax inside rules:if.

Question 30Pipeline configuration and authoring

Which keyword allows a job to be started by a user from the pipeline view and also blocks later stages until someone acts?

  1. when: on_success
  2. needs: []
  3. when: manual Correct answer.
  4. allow_failure: true

Explanation

when: manual creates a job that must be triggered by a user; by default such a job is blocking, so later stages wait for that action. Combining it with allow_failure: true would make it non-blocking, which is a different behavior.

Question 31Pipeline configuration and authoring

A configuration defines a hidden job .test_base with a script block, and a real job uses extends: .test_base while also declaring its own script. What is the resulting script for the real job?

  1. The real job's script replaces the inherited script entirely. Correct answer.
  2. The pipeline fails because script cannot be declared in both places.
  3. The two script lists are concatenated with the parent's lines first.
  4. The parent's script wins because extends is applied last.

Explanation

extends performs a reverse deep merge in which the child's keys take precedence, and arrays such as script are replaced rather than appended. To combine lines, the usual pattern is YAML anchors with merge keys or a before_script, since extends alone will not concatenate script entries.

Question 32Pipeline configuration and authoring

A job needs a value that is only defined in the project's CI/CD variables settings and must not appear in the job log. Which variable type should be used?

  1. An instance-level variable
  2. A masked variable Correct answer.
  3. A file-type variable
  4. A predefined variable

Explanation

Masked variables have their values redacted in job logs, which is the mechanism for keeping secrets out of trace output. Masking requires the value to satisfy character and length constraints, otherwise GitLab refuses to save it as masked.

Question 33Pipeline configuration and authoring

A job declares environment: name: review/$CI_COMMIT_REF_SLUG. What does GitLab create for each branch?

  1. An environment that only exists after a manual approval.
  2. A separate environment whose name includes the branch slug. Correct answer.
  3. A single shared environment named review.
  4. A protected environment tied to the default branch only.

Explanation

Variable expansion in the environment name produces a distinct environment per branch, which enables per-branch deployments and tracking. These dynamic environments also feed environment-scoped variables and stop actions when configured.

Question 34Pipeline configuration and authoring

Which keyword is used to pass a set of variables from a job that produces them to jobs in later stages?

  1. artifacts:reports:dotenv Correct answer.
  2. cache:key
  3. variables:export
  4. dependencies

Explanation

A dotenv report artifact stores key-value pairs that GitLab injects as variables into later jobs, which is the supported way to propagate runtime values. Plain cache and dependencies move files or artifacts but do not create variables from their contents.

Question 35Pipeline configuration and authoring

A job sets retry with when: [runner_system_failure, stuck_or_timeout_failure] and max: 2. How many total attempts can the job make?

  1. Three attempts in total. Correct answer.
  2. Two attempts in total.
  3. One attempt in total.
  4. Four attempts in total.

Explanation

max: 2 means up to two retries in addition to the initial run, giving three total attempts. The when list limits retries to the listed failure types, so other failures end the job immediately.

Question 36Pipeline configuration and authoring

A pipeline configuration sets workflow:rules that evaluate to never for a branch push, while a job's own rules would match. What happens to the pipeline?

  1. No pipeline is created for that push. Correct answer.
  2. The pipeline is created but all jobs are manual.
  3. The pipeline is created and the job is skipped.
  4. The pipeline is created with only the matching job.

Explanation

workflow:rules decide whether a pipeline is created at all; if no workflow rule allows the pipeline, it is not created and job-level rules are never evaluated. This differs from job rules, which only control whether individual jobs are added.

Question 37Pipeline configuration and authoring

Two jobs both declare cache with key: $CI_COMMIT_REF_SLUG and different paths. What is the practical effect on cache storage?

  1. GitLab merges both path lists into a single cache automatically.
  2. They share one cache archive per branch, so each job's upload can overwrite the other's contents. Correct answer.
  3. They receive separate caches because the paths differ.
  4. The second job's cache declaration is ignored as a duplicate key.

Explanation

The cache key determines the archive identity, so identical keys on the same branch map to the same cache; each job's upload can replace what the other stored. Distinct keys, for example by adding a job-specific suffix, are needed to keep the caches independent.

Question 38Pipeline configuration and authoring

A job must run only when a merge request pipeline exists, and must not appear in branch pipelines. Which rules clause is appropriate?

  1. if: '$CI_PIPELINE_SOURCE == "push"'
  2. if: '$CI_MERGE_REQUEST_ID' && '$CI_COMMIT_BRANCH'
  3. if: '$CI_OPEN_MERGE_REQUESTS'
  4. if: '$CI_PIPELINE_SOURCE == "merge_request_event"' Correct answer.

Explanation

Merge request pipelines are identified by CI_PIPELINE_SOURCE equal to merge_request_event, which is the reliable condition for restricting a job to them. CI_MERGE_REQUEST_* variables exist only in such pipelines, and CI_OPEN_MERGE_REQUESTS can be populated in branch pipelines as well.

Question 39Pipeline configuration and authoring

Which keyword lets a job reuse a container image for its execution environment while also overriding the image's entrypoint?

  1. before_script:image
  2. default:image:entrypoint
  3. image:name together with image:entrypoint Correct answer.
  4. services:name

Explanation

The image keyword accepts name and entrypoint sub-keys; setting entrypoint to an empty list is the common way to bypass an image's default entrypoint so the runner can execute the script. services has its own entrypoint handling and does not define the job's execution image.

Question 40Pipeline configuration and authoring

A job declares `parallel: 4` and also uses `needs:` to depend on a job in an earlier stage. How many downstream jobs must list that parallelized job, and what must each entry reference?

  1. Each downstream job lists one `needs` entry per parallel instance, using the base job name plus the instance index such as `build 1` through `build 4`. Correct answer.
  2. Each downstream job must disable `needs` because parallel jobs cannot be referenced across stages.
  3. Each downstream job lists one `needs` entry per parallel instance, using the base job name alone repeated four times.
  4. Each downstream job lists a single `needs` entry with the base job name, and GitLab waits for every parallel instance to finish.

Explanation

When a job uses `parallel`, GitLab creates that many separate jobs named after the base job plus a numeric suffix (`build 1`, `build 2`, and so on). A downstream job that uses `needs` must name each of those instances explicitly, one entry per instance, because the base name alone does not match any actual job. This lets the downstream job start as soon as all of the referenced parallel instances complete rather than waiting for the whole stage.

Question 41Runners, executors, and job execution environment

In GitLab Runner configuration, which executor runs each job in a fresh Docker container and requires an image to be specified either in the config or in the job?

  1. shell
  2. virtualbox
  3. docker Correct answer.
  4. ssh

Explanation

The docker executor pulls an image and starts a container for each job, so an image must come from the runner config.toml or from the job's image keyword. The shell executor runs directly on the host, and ssh and virtualbox do not create per-job Docker containers.

Question 42Runners, executors, and job execution environment

A job needs a variable that should never appear in job logs. Which GitLab CI/CD keyword should be used to define it?

  1. variables with masked set to true at job level
  2. the masked attribute on the variable Correct answer.
  3. the protected attribute on the variable
  4. the hidden attribute on the variable

Explanation

Variables marked masked have their values replaced with [MASKED] in job logs, provided the value meets masking requirements such as minimum length and character set. Protected only restricts which branches can access the variable, and hidden applies to job names rather than variables.

Question 43Runners, executors, and job execution environment

Which file does a GitLab Runner read for its global configuration, such as concurrent and the list of runners?

  1. /etc/gitlab-runner/config.toml Correct answer.
  2. /etc/gitlab-runner/.gitlab-ci.yml
  3. /etc/gitlab/runner-config.json
  4. /home/gitlab-runner/runner.yaml

Explanation

GitLab Runner stores its configuration in config.toml, typically at /etc/gitlab-runner/config.toml when installed as root. It defines global settings like concurrent and per-runner sections including executor and token.

Question 44Runners, executors, and job execution environment

What does the concurrent value in a runner's config.toml control?

  1. The number of jobs a single runner can execute at the same time Correct answer.
  2. The number of artifacts a job can upload
  3. The maximum number of retries for a failed job
  4. The number of pipeline stages GitLab allows in one pipeline

Explanation

concurrent sets how many jobs one runner process may run simultaneously. Setting it higher than the available CPU or executor capacity can cause jobs to queue or contend for resources.

Question 45Runners, executors, and job execution environment

Which keyword in .gitlab-ci.yml selects which runner picks up a job by matching runner tags?

  1. labels
  2. tags Correct answer.
  3. runner
  4. executor

Explanation

The tags keyword lists the runner tags a job requires; GitLab only dispatches the job to runners carrying all of those tags. Runners are registered with tags, and jobs without matching tags stay pending.

Question 46Runners, executors, and job execution environment

A job must run before any other job in the pipeline regardless of stage order, to prepare a shared resource. Which keyword accomplishes this?

  1. needs: [] Correct answer.
  2. before_script
  3. rules
  4. stage: pre

Explanation

Setting needs to an empty array makes the job start immediately without waiting for earlier stages. This is commonly used for setup jobs that must run first despite their stage placement.

Question 47Runners, executors, and job execution environment

Which GitLab Runner executor is the only one that supports running jobs directly on the host without additional isolation software?

  1. docker-autoscaler
  2. docker
  3. shell Correct answer.
  4. kubernetes

Explanation

The shell executor runs job scripts directly using the host's shell and installed tools, requiring no container or VM layer. This makes it simple but exposes the host to job side effects.

Question 48Runners, executors, and job execution environment

What is the purpose of the GIT_STRATEGY variable in a job?

  1. It determines which Git remote is used for pushing tags
  2. It sets the Git commit strategy for merging branches
  3. It configures the Git LFS transfer mode
  4. It controls how the runner fetches or clones the repository before running the script Correct answer.

Explanation

GIT_STRATEGY controls repository retrieval: clone re-clones, fetch reuses the working copy and fetches, and none skips retrieval. It is useful for jobs that need no source or need a clean checkout.

Question 49Runners, executors, and job execution environment

A job using the docker executor needs to build container images. Which configuration enables Docker-in-Docker for that job?

  1. Setting privileged to false and using the shell executor
  2. Using the kubernetes executor with no service
  3. Adding a service entry for docker:dind and setting DOCKER_HOST to tcp://docker:2376 or the appropriate dind address Correct answer.
  4. Mounting the host Docker socket by default without any service

Explanation

Docker-in-Docker requires a dind service container and pointing the Docker client at it, typically via DOCKER_HOST, along with TLS or privileged settings as required. The runner must also permit the necessary privileged mode.

Question 50Runners, executors, and job execution environment

Which statement about the cache keyword in GitLab CI/CD is accurate?

  1. Cache is guaranteed to be restored for every job that requests the same key
  2. Cache entries are stored on the runner host or object storage and may be missing if not yet populated Correct answer.
  3. Cache replaces artifacts for passing files between stages
  4. Cache is uploaded to GitLab and always available across all runners regardless of configuration

Explanation

Caches are stored where the runner is configured to keep them, such as local disk or S3, and are best-effort; a job may find no cache on first run or when the key differs. Artifacts, not cache, are the reliable way to pass files between stages.