How Pipeline Configuration Works

.git uses a declarative YAML schema to define build, test, and deployment workflows. When you push to a repository containing a .git-ci.yaml file, the engine parses the configuration and spins up isolated runners for each job.

💡 Pro Tip Place your pipeline config at the root of your repository. We auto-detect frameworks (Node, Python, Go, Rust, etc.) and apply sensible defaults if keys are omitted.

Basic Pipeline Structure

A minimal pipeline requires a stages list defining sequential execution blocks. Each stage contains one or more jobs that run in parallel.

.git-ci.yaml
name: default-pipeline
stages:
  - name: build
    jobs:
      - name: compile-app
        run: npm ci && npm run build

  - name: test
    jobs:
      - name: unit-tests
        run: npm test
      - name: lint
        run: npm run lint

  - name: deploy
    jobs:
      - name: prod-push
        run: .git deploy --env production

Key Properties

Field Type Description
name string Display name for the pipeline run
stages array Sequential execution blocks
jobs[].name string Unique identifier within the stage
jobs[].run string | array Shell commands to execute
jobs[].image string Base container (e.g., node:20-alpine)

Triggers & Branch Rules

Control when pipelines execute using triggers. Support includes push events, pull requests, scheduled cron jobs, and manual dispatch.

Branch-aware triggers
triggers:
  - type: push
    branches:
      - main
      - release/**
  - type: pull_request
    branches:
      - main
  - type: schedule
    cron: "0 2 * * 1" # Mondays at 2 AM UTC
    jobs: ["cleanup-stale-images"]
📌 Note Trigger evaluation is additive. If multiple rules match, the pipeline runs once with merged configuration. Use only and except for fine-grained control.

Environments & Secrets

Inject configuration securely using env blocks. Secrets are encrypted at rest and never logged. Environment scoping ensures production credentials never leak into preview branches.

Environment variables
env:
  global:
    NODE_ENV: production
    ENABLE_TELEMETRY: "true"

  stages:
    test:
      CI_DATABASE_URL: postgres://test:pass@localhost:5432/db
    deploy:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}

To manage secrets, use the .git secrets CLI or the Dashboard Settings → Environments panel. Variables use Go-template syntax with built-in functions like ${{ upper(env.VAR) }}.

Caching & Optimization

Reduce build times by persisting dependencies and build artifacts across runs. Cache keys are deterministic and support fallback chains.

Dependency caching
cache:
  - key: npm-{{ hashFiles("package-lock.json") }}
    paths: ["node_modules"]
  - key: build-{{ hashFiles("src/**") }}
    paths: [".next/cache"]
    restore-keys:
      - build-
⚠️ Important Cache storage is scoped to your organization. Exceeding the 50GB limit will evict least-recently-used keys. Monitor usage in Dashboard → Storage.

Best Practices

  • Pin base images using specific tags (e.g., node:20.9.0-alpine) to avoid breaking changes.
  • Fail fast by placing linting and unit tests before heavy compilation or e2e suites.
  • Use matrix builds for cross-version testing: matrix: { node: [18, 20, 22] }
  • Limit concurrency with max_parallel: 4 to prevent runner queue saturation.
  • Validate YAML locally using .git ci lint before committing.