Ruby Gems
Detects Ruby & Bundler versions, uses Gemfile.lock for checksums
Cigen can inject restore/save cache steps when a job declares cache:. Cache definitions are extensible via YAML; key calculation is simple by default and can be customized.
By default, injected keys include the cache name and the selected architecture, plus a checksum expression. You can override keys via cache_definitions if you need a specific pattern.
Cigen ships default definitions for common technologies that you can extend or override. These drive detection and provide sensible paths; key templates can be provided if desired.
Ruby Gems
Detects Ruby & Bundler versions, uses Gemfile.lock for checksums
Node Modules
Supports npm, yarn, pnpm, and bun with appropriate lock files
Python Packages
Handles pip, pipenv, and poetry with virtual environment detection
Go Modules
Uses go.mod and go.sum for dependency tracking
cache_definitions:gems: versions: [ruby, bundler] checksum_sources: [Gemfile, Gemfile.lock] paths: [vendor/bundle, .bundle]cache_definitions:node_modules: versions: [node] checksum_sources: - package.json - detect: [package-lock.json, yarn.lock, bun.lockb, pnpm-lock.yaml] paths: [node_modules]cache_definitions:pip: versions: [python, pip] checksum_sources: - detect: [requirements.txt, Pipfile] - detect_optional: [requirements.lock, Pipfile.lock] paths: - detect: [.venv, venv] - ~/.cache/pipThe cache and restore_cache fields serve different purposes:
cache: restores before steps and saves after steps for the named cachesrestore_cache: restores only (read-only)# Read and write cachejobs: build: cache: gems # Restores before steps, saves after steps
# Read-only cachejobs: test: restore_cache: gems # Only restores, doesn't saveThe restore_cache field is a shorthand for:
cache: gems: restore: true # Always true by default anyway save: false # This is what restore_cache doesjobs:test: image: cimg/ruby:3.3 cache: gems # Uses all defaults from gems cache definition steps: - run: bundle install - run: bundle exec rspecThis injects a restore_cache step before, and a save_cache step after, when the cache is declared on the job.
jobs:full_stack_test: image: cimg/ruby:3.3 cache: [gems, node_modules] # Multiple cache types services: [postgres] steps: - run: bundle install - run: npm install - run: bundle exec rspecjobs:test: image: cimg/ruby:3.3 cache: gems: paths: [vendor/rubygems, .bundle] # Override paths # versions and checksum_sources from definition steps: - run: bundle install --path vendor/rubygems# In config.ymlcache_definitions:ml_models: versions: [python] checksum_sources: - requirements-ml.txt - models/config.json paths: - models/cache - ~/.cache/torch
webpack*assets:checksum_sources: # No versions - pure checksum cache - package.json - webpack.config.js - src/**/_.jspaths: - dist/assets - .webpack-cacheFor caches that don’t depend on runtime versions:
cache_definitions:static_assets: checksum_sources: [assets/**/*.css, assets/**/*.js] paths: [public/compiled-assets]Example key: linux-ubuntu22.04-amd64-static_assets-abc123def456
paths:- node_modules # Required - job fails if missing- detect: # At least one must exist - .venv - venv - virtualenv- detect_optional: # All are optional - .cache/pre-commit - ~/.cache/myappFor fine-grained control, use manual cache steps:
steps:- restore_cache: name: Restore webpack cache key: webpack-{{ checksum "webpack.config.js" }}
- name: Build assetsrun: npm run build
- save_cache:name: Save webpack cachekey: webpack-{{ checksum "webpack.config.js" }}paths: [.webpack-cache, dist/]These steps:
Configure different storage backends for various scenarios:
cache_backends:default: native # Use CI provider's native cache
# Backend configurations
s3:bucket: my-cache-bucketregion: us-east-1prefix: cigen-cache/
redis:url: redis://cache.example.com:6379ttl: 604800 # 7 days
minio:endpoint: minio.internal:9000bucket: ci-cacheaccess_key: ${MINIO_ACCESS_KEY}secret_key: ${MINIO_SECRET_KEY}
# Per-cache backend override
cache_definitions:ml_models:backend: s3 # Large models go to S3paths: [models/]Version sources are checked in order until one succeeds:
Version files - Read directly from committed files
- file: .ruby-version # Contains: 3.3.0Tool version files - Extract using patterns
- file: .tool-versions pattern: 'ruby (.+)' # From: ruby 3.3.0Runtime commands - Query installed versions
- command: 'ruby --version' # Auto-parses version numbersRaw commands - Use output directly
- command: "grep -A1 'BUNDLED WITH' Gemfile.lock | tail -n1" parse_version: false # Use raw outputWhen multiple versions are detected:
linux-ubuntu22.04-amd64-fullstack-ruby3.3.0-node20.11.0-abc123defCache keys automatically include architecture information:
jobs:build: architectures: [amd64, arm64] cache: gems
# Generates separate cache keys:
# linux-ubuntu22.04-amd64-gems-ruby3.3.0-abc123def
# linux-ubuntu22.04-arm64-gems-ruby3.3.0-abc123defUse Built-in Types
Leverage built-in cache definitions when possible - they handle edge cases and evolve with best practices
Include Lock Files
Always include both manifest files (package.json) and lock files (package-lock.json) in checksum sources
Version Files in Git
Commit version files (.ruby-version, .node-version) to ensure consistent cache keys across environments
Descriptive Names
Use clear, descriptive cache names (gems, node_modules) rather than generic names (cache1, deps)
If caches aren’t restoring when expected:
cigen generate --verboseFor jobs needing different cache strategies:
# Different cache strategies for same dependency typecache_definitions:gems_production: type: gems # Inherit from gems paths: [vendor/production-gems]
gems_development:type: gemspaths: [vendor/development-gems, .bundle]Cigen chooses cache backends based on:
The same cache configuration works across all backends - cigen handles the implementation details.