What is a basic GitLab CI/CD pipeline and how do you trigger one?
Quick Answer
A GitLab CI/CD pipeline is a collection of jobs organized into stages that execute automatically when code is pushed to the repository. A basic pipeline is triggered by committing a .gitlab-ci.yml file to the project root, after which every subsequent push, merge request, or scheduled event creates a new pipeline instance.
Detailed Answer
Think of a GitLab pipeline like an automated assembly line in a factory that starts rolling the moment a delivery truck arrives. The truck (git push) delivers raw materials (code changes) to the factory entrance (GitLab server). The assembly line (pipeline) kicks into gear automatically, moving the materials through quality inspection (lint), manufacturing (build), testing (test), and shipping (deploy). No human needs to press a start button; the arrival of materials triggers the entire process.
A pipeline in GitLab is the top-level container for all CI/CD work. It consists of stages (ordered phases) and jobs (individual tasks within stages). The simplest possible pipeline requires only a .gitlab-ci.yml file at the repository root with at least one job containing a script keyword. When you push this file to GitLab, the CI/CD engine detects it, parses the configuration, creates a pipeline record, and begins scheduling jobs for execution. Pipelines are triggered by several events: pushing commits to any branch, creating or updating a merge request, on a cron schedule defined in the GitLab UI under CI/CD > Schedules, manually through the 'Run pipeline' button in the web interface, or via the GitLab API. Each pipeline is associated with a specific commit SHA and branch, creating a direct link between code changes and their automated validation.
Internally, when a push event reaches the GitLab server, the webhook processor extracts the branch name and commit SHA. The CI/CD subsystem fetches the .gitlab-ci.yml content from that specific commit (not from the default branch, but from the pushed branch itself). It parses and validates the YAML, resolves any include directives, expands variables, and evaluates workflow rules to determine if a pipeline should be created at all. If the pipeline proceeds, GitLab evaluates each job's rules or only/except conditions against the current context (branch name, whether it is a merge request, whether variables match) to determine which jobs to include. Included jobs are organized by stage, assigned a created status, and stored in the database. GitLab Runners continuously poll the server for pending jobs matching their tags and capabilities. When a Runner picks up a job, it transitions to running, and log output streams back to the GitLab interface in real time.
In production, teams rarely trigger pipelines manually. The standard workflow for a service like search-indexer relies on automatic triggers: developers push to feature branches, which triggers a pipeline running lint, build, and test stages. When they open a merge request, a merge request pipeline runs the same stages plus a security scan. When the MR is merged to main, a production pipeline runs all stages including deployment to staging and, with manual approval gates, deployment to production. Scheduled pipelines run nightly to execute long-running performance tests or dependency vulnerability scans that are too slow for every push. The pipeline trigger token feature allows external systems (like a separate repository or a monitoring alert) to start pipelines via API, enabling cross-project orchestration.
A common gotcha for beginners is expecting the pipeline to run when they first add the .gitlab-ci.yml file but finding that nothing happens. This usually occurs because the project does not have any GitLab Runners available. Shared Runners must be enabled in the project settings, or specific Runners must be registered and assigned to the project. Another mistake is writing a .gitlab-ci.yml that triggers pipelines on every branch including branches that do not need CI, wasting Runner resources. Use the workflow keyword or rules to control which branches trigger pipelines, such as only running the full pipeline on main and merge requests while running a minimal lint-only pipeline on other branches.