Skip to content

Commit 652d22d

Browse files
committed
work on built-in package manager support
1 parent 6c64439 commit 652d22d

37 files changed

Lines changed: 1951 additions & 73 deletions

File tree

docs/src/content/docs/configuration/packages.mdx

Lines changed: 141 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Package Management
3-
description: Intelligent package installation with automatic caching and deduplication
3+
description: Dynamic package manager detection and installation built on top of the caching system
44
---
55

66
import {
@@ -11,38 +11,88 @@ import {
1111
Card,
1212
} from '@astrojs/starlight/components';
1313

14-
The `packages` feature provides a high-level abstraction for package management that combines intelligent caching with automatic installation commands.
14+
The `packages` feature provides intelligent package manager detection, installation, and optimization that builds on top of cigen's [cache system](/configuration/cache). It automatically detects which package manager your project uses and generates the correct installation commands.
1515

16-
## What Are Packages?
16+
## Architecture Overview
1717

18-
<Aside type="tip">
19-
**Packages = Installation + Caching**: The `packages` field automatically
20-
handles both installing dependencies and caching them efficiently.
18+
<Aside type="note">
19+
**Packages builds on Cache**: The package system leverages the existing cache system for storage and retrieval, while adding package manager detection and installation logic on top.
2120
</Aside>
2221

23-
While the `cache` field handles storage and retrieval, `packages` goes further by:
22+
The package management system provides:
2423

25-
1. **Restoring** the package cache if it exists
26-
2. **Running** the appropriate install command
27-
3. **Saving** the updated cache for future runs
28-
4. **Optimizing** workflows through smart deduplication
24+
1. **Dynamic package manager detection** - Detects npm vs yarn vs pnpm based on lock files
25+
2. **Configurable installation commands** - YAML-based definitions for any package manager
26+
3. **Smart job deduplication** - Optimizes workflows when multiple jobs use the same packages
27+
4. **Extensible definitions** - Built-in support for common languages, fully customizable
2928

30-
## Supported Package Managers
29+
## Package Manager Definitions
3130

32-
<CardGrid>
33-
<Card title="Node.js" icon="seti:javascript">
34-
npm, yarn, pnpm, bun - auto-detected from lock files
35-
</Card>
36-
<Card title="Ruby" icon="seti:ruby">
37-
Bundler with automatic Gemfile.lock detection
38-
</Card>
39-
<Card title="Python" icon="seti:python">
40-
pip, pipenv, poetry with virtual environment support
41-
</Card>
42-
<Card title="Go" icon="seti:go">
43-
Go modules with automatic go.mod detection
44-
</Card>
45-
</CardGrid>
31+
Package managers are defined in YAML configuration with detection rules and installation commands. Cigen includes built-in definitions that you can extend or override.
32+
33+
### Built-in Package Managers
34+
35+
<Code
36+
code={`# Built into cigen's default configuration
37+
package_managers:
38+
node:
39+
versions: [node]
40+
detect:
41+
- npm:
42+
lockfile: package-lock.json
43+
command: npm ci
44+
- yarn:
45+
lockfile: yarn.lock
46+
command: yarn install --frozen-lockfile
47+
- pnpm:
48+
lockfile: pnpm-lock.yaml
49+
command: pnpm install --frozen-lockfile
50+
- bun:
51+
lockfile: bun.lockb
52+
command: bun install --frozen-lockfile
53+
checksum_sources:
54+
- package.json
55+
- detect: [package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb]
56+
cache_paths: [node_modules]
57+
58+
ruby:
59+
versions: [ruby, bundler]
60+
detect:
61+
- bundler:
62+
lockfile: Gemfile.lock
63+
command: bundle install
64+
checksum_sources: [Gemfile, Gemfile.lock]
65+
cache_paths: [vendor/bundle, .bundle]
66+
67+
python:
68+
versions: [python]
69+
detect:
70+
- pip:
71+
lockfile: requirements.txt
72+
command: pip install -r requirements.txt
73+
- pipenv:
74+
lockfile: Pipfile.lock
75+
command: pipenv install --deploy
76+
- poetry:
77+
lockfile: poetry.lock
78+
command: poetry install
79+
checksum_sources:
80+
- detect: [requirements.txt, Pipfile, pyproject.toml]
81+
- detect_optional: [requirements.lock, Pipfile.lock, poetry.lock]
82+
cache_paths:
83+
- detect: [.venv, venv]
84+
- ~/.cache/pip`}
85+
lang="yaml"
86+
title="Built-in package manager definitions"
87+
/>
88+
89+
### How Detection Works
90+
91+
When you use `packages: node`, cigen:
92+
93+
1. **Detects the specific tool** - Checks for `package-lock.json` (npm), `yarn.lock` (yarn), `pnpm-lock.yaml` (pnpm), or `bun.lockb` (bun)
94+
2. **Generates the install command** - Uses the appropriate command (`npm ci`, `yarn install --frozen-lockfile`, etc.)
95+
3. **Creates cache configuration** - Leverages the cache system with proper version detection and checksums
4696

4797
## Basic Usage
4898

@@ -52,17 +102,18 @@ While the `cache` field handles storage and retrieval, `packages` goes further b
52102
code={`jobs:
53103
test:
54104
image: cimg/node:18.0
55-
packages: [node] # Handles npm install + caching
105+
packages: node # Auto-detects npm/yarn/pnpm/bun
56106
steps:
57107
- run: npm test`}
58108
lang="yaml"
59109
title="Simple package usage"
60110
/>
61111

62112
This automatically:
63-
1. Restores node_modules cache
64-
2. Runs `npm install` (or yarn/pnpm/bun based on lock file)
65-
3. Saves the cache for future runs
113+
1. **Detects** which package manager based on lock files
114+
2. **Restores** the appropriate cache (e.g., `node_modules`)
115+
3. **Runs** the detected install command (e.g., `yarn install --frozen-lockfile`)
116+
4. **Saves** the cache with proper version and checksum keys
66117

67118
### Multiple Package Types
68119

@@ -93,17 +144,16 @@ When only one job uses a package manager, installation runs inline:
93144
<Code
94145
code={`jobs:
95146
test:
96-
packages: [node]
147+
packages: node
97148
steps:
98149
- run: npm test
99150
100151
# Generated structure:
101152
jobs:
102153
test:
154+
cache: node_modules # Uses cache system with detected package manager
103155
steps:
104-
- restore_cache: node_modules
105-
- run: npm install
106-
- save_cache: node_modules
156+
- run: yarn install --frozen-lockfile # Detected command
107157
- run: npm test`}
108158
lang="yaml"
109159
title="Single job - inline installation"
@@ -116,29 +166,30 @@ When multiple jobs use the same packages, cigen creates a dedicated job:
116166
<Code
117167
code={`jobs:
118168
test:
119-
packages: [node]
169+
packages: node
120170
steps:
121171
- run: npm test
122172
123173
lint:
124-
packages: [node]
174+
packages: node
125175
steps:
126176
- run: npm run lint
127177
128178
build:
129-
packages: [node]
179+
packages: node
130180
steps:
131181
- run: npm run build
132182
133183
# Generated structure:
134184
jobs:
135185
install_node_packages:
136-
packages: [node]
137-
# Only handles installation and caching
186+
cache: node_modules
187+
steps:
188+
- run: yarn install --frozen-lockfile # Detected based on yarn.lock
138189
139190
test:
140191
requires: [install_node_packages]
141-
restore_cache: node_modules # Read-only
192+
restore_cache: node_modules # Read-only cache access
142193
steps:
143194
- run: npm test
144195
@@ -210,53 +261,77 @@ Based on detection, cigen runs the appropriate command:
210261
| `python` | Pipfile.lock | `pipenv install --deploy` |
211262
| `go` | go.mod | `go mod download` |
212263

213-
## Advanced Configuration
264+
## Customizing Package Managers
214265

215-
### Custom Install Commands
266+
### Overriding Built-in Definitions
216267

217-
Override the default install command when needed:
268+
You can customize the built-in package manager definitions in your configuration:
218269

219270
<Code
220-
code={`jobs:
221-
test:
222-
packages:
223-
node:
224-
command: npm ci --production # Custom command
225-
steps:
226-
- run: npm test`}
271+
code={`# .cigen/cigen.yml
272+
package_managers:
273+
node:
274+
# Override the npm command
275+
detect:
276+
- npm:
277+
lockfile: package-lock.json
278+
command: npm ci --production # Custom flags
279+
- yarn:
280+
lockfile: yarn.lock
281+
command: yarn install --frozen-lockfile --production
282+
# Keep other settings from built-in definition
283+
versions: [node]
284+
checksum_sources:
285+
- package.json
286+
- detect: [package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb]
287+
cache_paths: [node_modules]`}
227288
lang="yaml"
228-
title="Custom install command"
289+
title="Custom package manager commands"
229290
/>
230291

231-
### Package-Specific Paths
292+
### Adding New Package Managers
232293

233-
Customize cache paths for specific scenarios:
294+
Define completely new package managers:
234295

235296
<Code
236-
code={`jobs:
237-
test:
238-
packages:
239-
ruby:
240-
paths: [vendor/bundle-ci] # Custom bundle path
241-
command: bundle install --path vendor/bundle-ci`}
297+
code={`# .cigen/cigen.yml
298+
package_managers:
299+
deno:
300+
versions: [deno]
301+
detect:
302+
- deno:
303+
lockfile: deno.lock
304+
command: deno cache deps.ts
305+
checksum_sources: [deps.ts, deno.lock]
306+
cache_paths: [~/.cache/deno]
307+
308+
swift:
309+
versions: [swift]
310+
detect:
311+
- spm:
312+
lockfile: Package.resolved
313+
command: swift package resolve
314+
checksum_sources: [Package.swift, Package.resolved]
315+
cache_paths: [.build]`}
242316
lang="yaml"
243-
title="Custom cache paths"
317+
title="Adding new package managers"
244318
/>
245319

246-
### Conditional Installation
320+
### Per-Job Customization
247321

248-
Control when packages are installed:
322+
Override package behavior for specific jobs:
249323

250324
<Code
251325
code={`jobs:
252-
deploy:
326+
test:
253327
packages:
254328
node:
255-
when: << pipeline.parameters.install_deps >>
329+
command: npm ci --ignore-optional # Job-specific command
330+
cache_paths: [node_modules, .npm] # Additional cache paths
256331
steps:
257-
- run: npm run deploy`}
332+
- run: npm test`}
258333
lang="yaml"
259-
title="Conditional installation"
334+
title="Per-job package customization"
260335
/>
261336

262337
## Packages vs Cache
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
version: 1
2+
provider: circleci
3+
output_path: .circleci
4+
output_filename: config.yml
5+
6+
docker_images:
7+
node:
8+
default: cimg/node:20.11.0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
image: node
2+
packages: node
3+
steps:
4+
- run:
5+
name: Build application
6+
command: npm run build
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
image: node
2+
packages: node
3+
steps:
4+
- run:
5+
name: Run ESLint
6+
command: npm run lint
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
image: node
2+
packages: node
3+
steps:
4+
- run:
5+
name: Run tests
6+
command: npm test

examples/packages_test/package-lock.json

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: 1
2+
provider: circleci
3+
output_path: .circleci
4+
output_filename: config.yml
5+
6+
docker_images:
7+
node:
8+
default: cimg/node:20.11.0
9+
10+
workflows:
11+
test:
12+
jobs:
13+
build:
14+
image: node
15+
packages: node
16+
steps:
17+
- run:
18+
name: Build application
19+
command: npm run build
20+
21+
test:
22+
image: node
23+
packages: node
24+
steps:
25+
- run:
26+
name: Run tests
27+
command: npm test
28+
29+
lint:
30+
image: node
31+
packages: node
32+
steps:
33+
- run:
34+
name: Run ESLint
35+
command: npm run lint

0 commit comments

Comments
 (0)