Create a Working GitLab CI/CD Pipeline with .gitlab-ci.yml at Repository Root
A practical guide to adding .gitlab-ci.yml at the repository root, matching runner tags, and verifying a build-test pipeline in GitLab CI/CD with checks and recovery steps.
21 Sept 2025, 16:13 UTC

Problem: pushes run nothing because the pipeline definition is missing or unreachable
The most common blocker is a missing or misplaced .gitlab-ci.yml. GitLab only triggers a pipeline when it can read that file from the repository root on a push, merge request, or scheduled trigger. If the file is absent, in a subfolder, or the runner cannot match the job tags, jobs stay pending and nothing builds.
Desired outcome
A pipeline that runs on every push to main and on merge requests, executes build and test jobs on a registered runner, and reports pass/fail in CI/CD > Pipelines with logs you can inspect.
Prerequisites
- A GitLab project with Developer role or higher to edit files and CI/CD settings.
- At least one GitLab CI/CD Runner registered to the project or group and online. Runners execute jobs; without a matching runner jobs remain pending.
- Access to set CI/CD variables for secrets. Do not store plain-text secrets in source. Use masked CI/CD variables at project, group, or instance level.
Focused procedure
1. Create the pipeline definition
Create .gitlab-ci.yml in the repository root. The file defines stages and jobs. Tags route jobs to runners.
stages:
- build
- test
variables:
NODE_VERSION: "20"
build-job:
stage: build
tags:
- docker
image: node:${NODE_VERSION}
script:
- echo "Installing dependencies"
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
test-job:
stage: test
tags:
- docker
image: node:${NODE_VERSION}
needs:
- job: build-job
artifacts: true
script:
- npm ci
- npm test
Replace docker tag with the tag your runner advertises. Mismatched tags cause jobs to stay pending.
2. Commit and push
Run locally in the repo root with a user that can push:
git add .gitlab-ci.yml
git commit -m "Add CI pipeline with build and test"
git push origin main
Push triggers the pipeline automatically. Merge request pipelines trigger on MR creation and updates.
3. Validate locally before pushing
If a runner is installed locally, you can dry-run a job step with the runner CLI. Run on a machine with gitlab-runner installed and permissions to execute shell commands:
gitlab-runner exec shell build-job
This executes the job script in your shell environment. It does not guarantee GitLab behavior but surfaces syntax errors in script steps.
Expected checks
- Open GitLab UI > CI/CD > Pipelines. A new pipeline appears for the push. The pipeline graph should show build-job then test-job.
- Each job shows a green checkmark on success. Click a job to view logs.
- Artifacts from build-job are available to test-job via needs.
Limitations: Pipeline triggers depend on branch protection and project settings. Scheduled pipelines require explicit schedule configuration. Self-hosted runners may be offline or lack required images, causing failures unrelated to YAML.
Recovery options
If jobs are pending: verify runner tags in Settings > CI/CD > Runners match job tags. If jobs fail: open the job log, fix the script or image, commit a new version of .gitlab-ci.yml and push. You can cancel a running pipeline from the Pipelines list and retry a single failed job from the job menu.
Secret exposure risk: if a secret was committed in plain text, rotate it immediately and remove the file from history. Use Settings > CI/CD > Variables with Masked enabled for sensitive data.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.