Faster CI
Install dependencies once, use everywhere
The packages feature provides intelligent package manager detection, installation, and optimization that builds on top of cigen’s cache system. It automatically detects which package manager your project uses and generates the correct installation commands.
The package management system provides:
Package managers are defined in YAML configuration with detection rules and installation commands. Cigen includes built-in definitions that you can extend or override.
# Built into cigen's default configurationpackage_managers:node: versions: [node] detect: - npm: lockfile: package-lock.json command: npm ci - yarn: lockfile: yarn.lock command: yarn install --frozen-lockfile - pnpm: lockfile: pnpm-lock.yaml command: pnpm install --frozen-lockfile - bun: lockfile: bun.lockb command: bun install --frozen-lockfile checksum_sources: - package.json - detect: [package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb] cache_paths: [node_modules]
ruby: versions: [ruby, bundler] detect: - bundler: lockfile: Gemfile.lock command: bundle install checksum_sources: [Gemfile, Gemfile.lock] cache_paths: [vendor/bundle, .bundle]
python: versions: [python] detect: - pip: lockfile: requirements.txt command: pip install -r requirements.txt - pipenv: lockfile: Pipfile.lock command: pipenv install --deploy - poetry: lockfile: poetry.lock command: poetry install checksum_sources: - detect: [requirements.txt, Pipfile, pyproject.toml] - detect_optional: [requirements.lock, Pipfile.lock, poetry.lock] cache_paths: - detect: [.venv, venv] - ~/.cache/pipWhen you use packages: node, cigen:
package-lock.json (npm), yarn.lock (yarn), pnpm-lock.yaml (pnpm), or bun.lockb (bun)npm ci, yarn install --frozen-lockfile, etc.)jobs:test: image: cimg/node:18.0 packages: node # Auto-detects npm/yarn/pnpm/bun steps: - run: npm testThis does the following:
yarn install --frozen-lockfile)Note: saving caches occurs when the job declares cache:. If you only declare packages: without a cache: entry, cigen will generate install steps but will not automatically add a save step.
jobs:full_stack_test: image: cimg/ruby:3.3 packages: [ruby, node] # Multiple package managers services: [postgres] steps: - run: bundle exec rspec - run: npm testWhen only one job uses a package manager, installation runs inline:
jobs:test: packages: node steps: - run: npm test
# Generated structure:jobs:test: cache: node_modules # Uses cache system with detected package manager steps: - run: yarn install --frozen-lockfile # Detected command - run: npm testWhen multiple jobs use the same packages, cigen can create a dedicated job with installation steps. To enable caching in that job, declare the relevant caches in your config.
jobs:test: packages: node steps: - run: npm test
lint: packages: node steps: - run: npm run lint
build: packages: node steps: - run: npm run build
# Generated structure:jobs:install_node_packages: steps: - run: yarn install --frozen-lockfile # Detected based on yarn.lock
# Tip: add caching to the install job in your config if desired# cache: node_modules
test: requires: [install_node_packages] restore_cache: node_modules # Read-only cache access (when install job saves it) steps: - run: npm test
lint: requires: [install_node_packages] restore_cache: node_modules steps: - run: npm run lint
build: requires: [install_node_packages] restore_cache: node_modules steps: - run: npm run buildThe automatic job deduplication provides:
Faster CI
Install dependencies once, use everywhere
Better Parallelization
Installation runs in parallel with other setup tasks
Reduced Redundancy
No duplicate installation commands across jobs
Cache Efficiency
Single cache save operation reduces overhead
Cigen automatically detects which package manager to use:
package-lock.json → npmyarn.lock → yarnpnpm-lock.yaml → pnpmbun.lockb → bunGemfile.lock → bundlerrequirements.lock or Pipfile.lock → pip/pipenvBased on detection, cigen runs the appropriate command:
| Package Type | Lock File | Install Command |
|---|---|---|
node (npm) | package-lock.json | npm ci |
node (yarn) | yarn.lock | yarn install --frozen-lockfile |
node (pnpm) | pnpm-lock.yaml | pnpm install --frozen-lockfile |
node (bun) | bun.lockb | bun install --frozen-lockfile |
ruby | Gemfile.lock | bundle install |
python | requirements.txt | pip install -r requirements.txt |
python | Pipfile.lock | pipenv install --deploy |
go | go.mod | go mod download |
Cigen includes production-ready package manager definitions that are compiled into the binary. These defaults are organized as separate YAML files for maintainability:
src/packages/config_templates/├── package_managers/│ ├── node.yml│ ├── ruby.yml│ ├── python.yml│ ├── go.yml│ ├── rust.yml│ ├── java.yml│ └── dotnet.yml└── version_sources/ ├── node.yml ├── ruby.yml ├── bundler.yml ├── python.yml ├── go.yml ├── rustc.yml ├── cargo.yml ├── java.yml └── dotnet.ymlWhen you define package_managers or version_sources in your .cigen/config.yml, your configuration intelligently merges with these defaults:
You can customize the built-in package manager definitions in your configuration:
# .cigen/config.ymlpackage_managers:node: # Override the npm command detect: - npm: lockfile: package-lock.json command: npm ci --production # Custom flags - yarn: lockfile: yarn.lock command: yarn install --frozen-lockfile --production # Keep other settings from built-in definition versions: [node] checksum_sources: - package.json - detect: [package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb] cache_paths: [node_modules]You can also customize how versions are detected for cache keys:
# .cigen/config.ymlversion_sources:node: - file: .nvmrc - file: .node-version - file: package.json pattern: '"engines":\s*{\s*"node":\s*"([^"]+)"' - command: node --version parse_version: true
# Add custom version sourcecustom_tool: - file: .custom-version - command: custom-tool --version parse_version: false # Don't parse, use raw outputDefine completely new package managers:
# .cigen/config.ymlpackage_managers:deno: versions: [deno] detect: - deno: lockfile: deno.lock command: deno cache deps.ts checksum_sources: [deps.ts, deno.lock] cache_paths: [~/.cache/deno]
swift: versions: [swift] detect: - spm: lockfile: Package.resolved command: swift package resolve checksum_sources: [Package.swift, Package.resolved] cache_paths: [.build]Override package behavior for specific jobs:
jobs:test: packages: node: command: npm ci --ignore-optional # Job-specific command cache_paths: [node_modules, .npm] # Additional cache paths steps: - run: npm testUnderstanding when to use each:
Use packages when: | Use cache when: |
|---|---|
| Installing dependencies | Caching build artifacts |
| Standard package managers | Custom cache scenarios |
| Want automatic commands | Need fine control |
| Multiple jobs share deps | Single job optimization |
jobs:build: packages: [node] # Install dependencies cache: webpack: # Cache build artifacts paths: [dist/, .webpack-cache] checksum_sources: [webpack.config.js] steps: - run: npm run buildBefore (manual):
jobs: test: steps: - checkout - restore_cache: node_modules - run: npm install - save_cache: node_modules - run: npm testAfter (with packages):
jobs: test: packages: [node] steps: - run: npm testBefore (cache only):
jobs: test: cache: node_modules steps: - run: npm install # Still needed - run: npm testAfter (with packages):
jobs: test: packages: [node] # Includes installation steps: - run: npm testUse for Dependencies
Use packages for dependency installation, cache for build artifacts
Let Detection Work
Trust automatic lock file detection rather than specifying commands
Share When Possible
Let deduplication optimize when multiple jobs use the same packages
Version Lock Files
Always commit lock files to ensure reproducible builds
If the wrong package manager is used:
package_managers: node: detect: - name: pnpm # Force pnpm to be checked first lockfile: pnpm-lock.yaml command: pnpm install --frozen-lockfile - name: npm lockfile: package-lock.json command: npm ciIf your custom package manager configuration isn’t being used:
detect, checksum_sources, cache_paths, etc.)cigen validate to catch configuration errors earlyIf jobs aren’t sharing installation:
packages values across jobsIf packages are reinstalling unnecessarily:
--verbose flag