Your first .gitlab-ci.yml

GitLab CI/CD · Essentials · 10 min

A green pipeline on every push is the first step to reliable merges.

Create .gitlab-ci.yml in the repository root, commit and push. GitLab parses it and creates a pipeline immediately; syntax errors are reported on the pipeline page, and the Pipeline editor (Build, Pipeline editor) validates the file as you type.

A job is a top-level key that is not a reserved keyword. The essentials:

  • script: one command or a list of commands run by the runner's shell. If any command exits non-zero, the job fails.
  • image: the Docker image the job runs in, such as python:3.13 or node:22.
  • before_script and after_script: commands run before and after script. after_script runs even when the job fails, in a separate shell.
  • default: sets keywords like image and before_script for every job.

Each job starts with the repository already cloned into $CI_PROJECT_DIR, so there is no checkout step to write; GitLab fetches the commit for you (shallow by default, 20 commits).

Keep YAML strings safe: a command containing : (colon and space) or starting with special characters needs quotes, or the line is parsed as a mapping. When in doubt, quote the whole command.

Example

default:
  image: python:3.13-slim

stages: [test]

test:
  stage: test
  before_script:
    - pip install -r requirements.txt
  script:
    - python -m pytest -q        # 12 passed in 0.8s
    - "echo 'Result: done'"      # quoted because of the colon-space
  after_script:
    - echo "always runs, even on failure" 

Remember

  • Commit .gitlab-ci.yml at the root and push to start a pipeline
  • script is required; image picks the container
  • Code is already checked out into $CI_PROJECT_DIR

Watch out for

  • Unquoted commands containing ': ' break the YAML.

Check yourself

  1. Your job's second script command fails. What happens to after_script?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.gitlab.com/ci/quick_start/