Skip to content

Configuration Overview

Cigen uses its own universal configuration format that compiles to provider-specific CI configurations. This format is designed to be intuitive, reduce duplication, and work consistently across all CI platforms.

Our configuration format follows these core principles:

Intuitive over Provider-Specific

Use concepts that make sense to developers rather than platform-specific jargon

DRY (Don't Repeat Yourself)

Reduce duplication through better abstractions and smart defaults

Least Surprise

Support multiple syntaxes where it makes sense, inspired by Ruby/Rails

Provider-Agnostic

Avoid leaking provider-specific concepts into the universal configuration

Basic config.yml
$schema: https://cigen.dev/schemas/v1/config-schema.json
# Provider configuration
provider: circleci
output_path: .circleci
output_filename: config.yml
# Global variables
vars:
app_name: myapp
version: "1.0.0"
# Service definitions
services:
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: test
# Job definitions
jobs:
test:
image: cimg/ruby:3.3
services: [postgres]
steps: [shallow_checkout, { run: bundle exec rspec }]
# Workflow definitions
workflows:
main:
jobs: - test

Cigen supports both single-file and multi-file configurations:

.cigen/
└── config.yml
.cigen/
├── config.yml # Main configuration
├── config/ # Split configuration files
│ ├── services.yml
│ └── cache.yml
├── commands/ # Reusable command templates
│ ├── install_deps.yml
│ └── deploy.yml
└── workflows/ # Workflow definitions
├── test/
│ └── jobs/
│ ├── rspec.yml
│ └── lint.yml
└── deploy/
└── jobs/
└── production.yml

By default, cigen performs a fast, shallow checkout via a built-in shallow_checkout command. You can override behavior globally or per job using the checkout section (see CircleCI provider docs for parameters). Set shallow: false to use the standard checkout step.

Step syntax comparison
# Cigen format (clean and readable)
steps:
- name: Run tests
run: |
bundle exec rspec
- name: Upload coverage
run: coverage-reporter upload
# CircleCI format (more nested)
steps:
- run:
name: Run tests
command: |
bundle exec rspec
- run:
name: Upload coverage
command: coverage-reporter upload
Service container comparison
# Cigen format (clear separation)
services:
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: test
jobs:
test:
image: cimg/ruby:3.3
services: [postgres, redis]
# CircleCI format (mixed primary + services)
docker:
- image: cimg/ruby:3.3 # Primary container
- image: postgres:15 # Service container
environment:
POSTGRES_PASSWORD: test
- image: redis:7 # Another service
Docker auth comparison
# Cigen format (define once, use everywhere)
docker:
default_auth: dockerhub
auth:
dockerhub:
username: $DOCKERHUB_USERNAME
password: $DOCKERHUB_TOKEN
ghcr:
username: $GITHUB_ACTOR
password: $GITHUB_TOKEN
# CircleCI format (repeated for every image)
docker:
- image: myimage:latest
auth:
username: $DOCKERHUB_USERNAME
password: $DOCKERHUB_TOKEN
Cache management comparison
# Cigen format (automatic and intelligent)
cache:
- gems # Automatically detects Ruby version, Gemfile.lock
- node_modules # Automatically detects Node version, package-lock.json
# Or with customization
cache:
gems:
paths: [vendor/bundle, .bundle]
key_files: [Gemfile.lock, .ruby-version]
# CircleCI format (verbose and manual)
steps:
- restore_cache:
keys: - v1-gems-{{ checksum "Gemfile.lock" }}-{{ checksum ".ruby-version" }}
- run: bundle install
- save_cache:
key: v1-gems-{{ checksum "Gemfile.lock" }}-{{ checksum ".ruby-version" }}
paths: [vendor/bundle]
Multi-architecture builds
jobs:
build_image:
image: cimg/base:stable
architectures: [amd64, arm64] # Creates build_image_amd64 and build_image_arm64
resource_class: medium # Automatically maps to correct provider classes
steps:
- run: docker build -t myapp:latest .
Template variables
# Use variables and functions in any configuration value
vars:
postgres_version: "15"
environment: production
jobs:
test:
image: cimg/postgres:{{ postgres_version }}
environment:
NODE_ENV: {{ environment }}
steps: - name: Setup hosts
run: |
echo "{{ read('etc-hosts.txt') | trim }}" >> /etc/hosts
Automatic workflow discovery
# Directory structure
workflows/
├── test/
│ └── jobs/
│ ├── rspec.yml
│ └── lint.yml
└── deploy/
└── jobs/
└── production.yml
# Automatically creates these workflows:
workflows:
test:
jobs: [rspec, lint]
deploy:
jobs: [production]

All cigen configurations are validated against JSON schemas:

Schema validation
$schema: https://cigen.dev/schemas/v1/config-schema.json
# This enables:
# - Real-time validation in VS Code, Cursor, etc.
# - Autocomplete and documentation
# - Immediate error feedback

When migrating from existing CI platforms:

  1. Service containers → Define once in services section
  2. Cache steps → Replace with intelligent cache definitions
  3. Workflow definitions → Convert to directory structure
  4. Docker auth → Centralize in docker.auth section
  5. Step syntax → Use cleaner name/run format
  6. Commands → Move to separate files in commands/ directory