@patricio0312rev/skillset 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/LICENSE +21 -0
- package/README.md +176 -0
- package/bin/cli.js +37 -0
- package/package.json +55 -0
- package/src/commands/init.js +301 -0
- package/src/index.js +168 -0
- package/src/lib/config.js +200 -0
- package/src/lib/generator.js +166 -0
- package/src/utils/display.js +95 -0
- package/src/utils/readme.js +196 -0
- package/src/utils/tool-specific.js +233 -0
- package/templates/ai-engineering/agent-orchestration-planner/ SKILL.md +266 -0
- package/templates/ai-engineering/cost-latency-optimizer/ SKILL.md +270 -0
- package/templates/ai-engineering/doc-to-vector-dataset-generator/ SKILL.md +239 -0
- package/templates/ai-engineering/evaluation-harness/ SKILL.md +219 -0
- package/templates/ai-engineering/guardrails-safety-filter-builder/ SKILL.md +226 -0
- package/templates/ai-engineering/llm-debugger/ SKILL.md +283 -0
- package/templates/ai-engineering/prompt-regression-tester/ SKILL.md +216 -0
- package/templates/ai-engineering/prompt-template-builder/ SKILL.md +393 -0
- package/templates/ai-engineering/rag-pipeline-builder/ SKILL.md +244 -0
- package/templates/ai-engineering/tool-function-schema-designer/ SKILL.md +219 -0
- package/templates/architecture/adr-writer/ SKILL.md +250 -0
- package/templates/architecture/api-versioning-deprecation-planner/ SKILL.md +331 -0
- package/templates/architecture/domain-model-boundaries-mapper/ SKILL.md +300 -0
- package/templates/architecture/migration-planner/ SKILL.md +376 -0
- package/templates/architecture/performance-budget-setter/ SKILL.md +318 -0
- package/templates/architecture/reliability-strategy-builder/ SKILL.md +286 -0
- package/templates/architecture/rfc-generator/ SKILL.md +362 -0
- package/templates/architecture/scalability-playbook/ SKILL.md +279 -0
- package/templates/architecture/system-design-generator/ SKILL.md +339 -0
- package/templates/architecture/tech-debt-prioritizer/ SKILL.md +329 -0
- package/templates/backend/api-contract-normalizer/ SKILL.md +487 -0
- package/templates/backend/api-endpoint-generator/ SKILL.md +415 -0
- package/templates/backend/auth-module-builder/ SKILL.md +99 -0
- package/templates/backend/background-jobs-designer/ SKILL.md +166 -0
- package/templates/backend/caching-strategist/ SKILL.md +190 -0
- package/templates/backend/error-handling-standardizer/ SKILL.md +174 -0
- package/templates/backend/rate-limiting-abuse-protection/ SKILL.md +147 -0
- package/templates/backend/rbac-permissions-builder/ SKILL.md +158 -0
- package/templates/backend/service-layer-extractor/ SKILL.md +269 -0
- package/templates/backend/webhook-receiver-hardener/ SKILL.md +211 -0
- package/templates/ci-cd/artifact-sbom-publisher/ SKILL.md +236 -0
- package/templates/ci-cd/caching-strategy-optimizer/ SKILL.md +195 -0
- package/templates/ci-cd/deployment-checklist-generator/ SKILL.md +381 -0
- package/templates/ci-cd/github-actions-pipeline-creator/ SKILL.md +348 -0
- package/templates/ci-cd/monorepo-ci-optimizer/ SKILL.md +298 -0
- package/templates/ci-cd/preview-environments-builder/ SKILL.md +187 -0
- package/templates/ci-cd/quality-gates-enforcer/ SKILL.md +342 -0
- package/templates/ci-cd/release-automation-builder/ SKILL.md +281 -0
- package/templates/ci-cd/rollback-workflow-builder/ SKILL.md +372 -0
- package/templates/ci-cd/secrets-env-manager/ SKILL.md +242 -0
- package/templates/db-management/backup-restore-runbook-generator/ SKILL.md +505 -0
- package/templates/db-management/data-integrity-auditor/ SKILL.md +505 -0
- package/templates/db-management/data-retention-archiving-planner/ SKILL.md +430 -0
- package/templates/db-management/data-seeding-fixtures-builder/ SKILL.md +375 -0
- package/templates/db-management/db-performance-watchlist/ SKILL.md +425 -0
- package/templates/db-management/etl-sync-job-builder/ SKILL.md +457 -0
- package/templates/db-management/multi-tenant-safety-checker/ SKILL.md +398 -0
- package/templates/db-management/prisma-migration-assistant/ SKILL.md +379 -0
- package/templates/db-management/schema-consistency-checker/ SKILL.md +440 -0
- package/templates/db-management/sql-query-optimizer/ SKILL.md +324 -0
- package/templates/foundation/changelog-writer/ SKILL.md +431 -0
- package/templates/foundation/code-formatter-installer/ SKILL.md +320 -0
- package/templates/foundation/codebase-summarizer/ SKILL.md +360 -0
- package/templates/foundation/dependency-doctor/ SKILL.md +163 -0
- package/templates/foundation/dev-environment-bootstrapper/ SKILL.md +259 -0
- package/templates/foundation/dev-onboarding-builder/ SKILL.md +556 -0
- package/templates/foundation/docs-starter-kit/ SKILL.md +574 -0
- package/templates/foundation/explaining-code/SKILL.md +13 -0
- package/templates/foundation/git-hygiene-enforcer/ SKILL.md +455 -0
- package/templates/foundation/project-scaffolder/ SKILL.md +65 -0
- package/templates/foundation/project-scaffolder/references/templates.md +126 -0
- package/templates/foundation/repo-structure-linter/ SKILL.md +0 -0
- package/templates/foundation/repo-structure-linter/references/conventions.md +98 -0
- package/templates/frontend/animation-micro-interaction-pack/ SKILL.md +41 -0
- package/templates/frontend/component-scaffold-generator/ SKILL.md +562 -0
- package/templates/frontend/design-to-component-translator/ SKILL.md +547 -0
- package/templates/frontend/form-wizard-builder/ SKILL.md +553 -0
- package/templates/frontend/frontend-refactor-planner/ SKILL.md +37 -0
- package/templates/frontend/i18n-frontend-implementer/ SKILL.md +44 -0
- package/templates/frontend/modal-drawer-system/ SKILL.md +377 -0
- package/templates/frontend/page-layout-builder/ SKILL.md +630 -0
- package/templates/frontend/state-ux-flow-builder/ SKILL.md +23 -0
- package/templates/frontend/table-builder/ SKILL.md +350 -0
- package/templates/performance/alerting-dashboard-builder/ SKILL.md +162 -0
- package/templates/performance/backend-latency-profiler-helper/ SKILL.md +108 -0
- package/templates/performance/caching-cdn-strategy-planner/ SKILL.md +150 -0
- package/templates/performance/capacity-planning-helper/ SKILL.md +242 -0
- package/templates/performance/core-web-vitals-tuner/ SKILL.md +126 -0
- package/templates/performance/incident-runbook-generator/ SKILL.md +162 -0
- package/templates/performance/load-test-scenario-builder/ SKILL.md +256 -0
- package/templates/performance/observability-setup/ SKILL.md +232 -0
- package/templates/performance/postmortem-writer/ SKILL.md +203 -0
- package/templates/performance/structured-logging-standardizer/ SKILL.md +122 -0
- package/templates/security/auth-security-reviewer/ SKILL.md +428 -0
- package/templates/security/dependency-vulnerability-triage/ SKILL.md +495 -0
- package/templates/security/input-validation-sanitization-auditor/ SKILL.md +76 -0
- package/templates/security/pii-redaction-logging-policy-builder/ SKILL.md +65 -0
- package/templates/security/rbac-policy-tester/ SKILL.md +80 -0
- package/templates/security/secrets-scanner/ SKILL.md +462 -0
- package/templates/security/secure-headers-csp-builder/ SKILL.md +404 -0
- package/templates/security/security-incident-playbook-generator/ SKILL.md +76 -0
- package/templates/security/security-pr-checklist-skill/ SKILL.md +62 -0
- package/templates/security/threat-model-generator/ SKILL.md +394 -0
- package/templates/testing/contract-testing-builder/ SKILL.md +492 -0
- package/templates/testing/coverage-strategist/ SKILL.md +436 -0
- package/templates/testing/e2e-test-builder/ SKILL.md +382 -0
- package/templates/testing/flaky-test-detective/ SKILL.md +416 -0
- package/templates/testing/integration-test-builder/ SKILL.md +525 -0
- package/templates/testing/mocking-assistant/ SKILL.md +383 -0
- package/templates/testing/snapshot-test-refactorer/ SKILL.md +375 -0
- package/templates/testing/test-data-factory-builder/ SKILL.md +449 -0
- package/templates/testing/test-reporting-triage-skill/ SKILL.md +469 -0
- package/templates/testing/unit-test-generator/ SKILL.md +548 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-actions-pipeline-creator
|
|
3
|
+
description: Creates comprehensive GitHub Actions CI/CD workflows for linting, testing, building, and deploying. Includes caching strategies, matrix builds, artifact handling, and failure diagnostics. Use for "GitHub Actions", "CI pipeline", "workflow automation", or "continuous integration".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GitHub Actions Pipeline Creator
|
|
7
|
+
|
|
8
|
+
Build production-ready GitHub Actions workflows with best practices.
|
|
9
|
+
|
|
10
|
+
## Basic CI Workflow
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
# .github/workflows/ci.yml
|
|
14
|
+
name: CI
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
branches: [main, develop]
|
|
19
|
+
pull_request:
|
|
20
|
+
branches: [main]
|
|
21
|
+
|
|
22
|
+
# Cancel in-progress runs for same workflow
|
|
23
|
+
concurrency:
|
|
24
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
25
|
+
cancel-in-progress: true
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
lint:
|
|
29
|
+
name: Lint
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Setup Node.js
|
|
35
|
+
uses: actions/setup-node@v4
|
|
36
|
+
with:
|
|
37
|
+
node-version: "20"
|
|
38
|
+
cache: "npm"
|
|
39
|
+
|
|
40
|
+
- name: Install dependencies
|
|
41
|
+
run: npm ci
|
|
42
|
+
|
|
43
|
+
- name: Run ESLint
|
|
44
|
+
run: npm run lint
|
|
45
|
+
|
|
46
|
+
- name: Run Prettier
|
|
47
|
+
run: npm run format:check
|
|
48
|
+
|
|
49
|
+
- name: Run TypeScript
|
|
50
|
+
run: npm run type-check
|
|
51
|
+
|
|
52
|
+
test:
|
|
53
|
+
name: Test
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Setup Node.js
|
|
59
|
+
uses: actions/setup-node@v4
|
|
60
|
+
with:
|
|
61
|
+
node-version: "20"
|
|
62
|
+
cache: "npm"
|
|
63
|
+
|
|
64
|
+
- name: Install dependencies
|
|
65
|
+
run: npm ci
|
|
66
|
+
|
|
67
|
+
- name: Run tests
|
|
68
|
+
run: npm test -- --coverage
|
|
69
|
+
|
|
70
|
+
- name: Upload coverage
|
|
71
|
+
uses: codecov/codecov-action@v3
|
|
72
|
+
with:
|
|
73
|
+
files: ./coverage/coverage-final.json
|
|
74
|
+
flags: unittests
|
|
75
|
+
fail_ci_if_error: true
|
|
76
|
+
|
|
77
|
+
build:
|
|
78
|
+
name: Build
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
needs: [lint, test]
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/checkout@v4
|
|
83
|
+
|
|
84
|
+
- name: Setup Node.js
|
|
85
|
+
uses: actions/setup-node@v4
|
|
86
|
+
with:
|
|
87
|
+
node-version: "20"
|
|
88
|
+
cache: "npm"
|
|
89
|
+
|
|
90
|
+
- name: Install dependencies
|
|
91
|
+
run: npm ci
|
|
92
|
+
|
|
93
|
+
- name: Build
|
|
94
|
+
run: npm run build
|
|
95
|
+
env:
|
|
96
|
+
NODE_ENV: production
|
|
97
|
+
|
|
98
|
+
- name: Upload build artifacts
|
|
99
|
+
uses: actions/upload-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: dist
|
|
102
|
+
path: dist/
|
|
103
|
+
retention-days: 7
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Matrix Strategy
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
test:
|
|
110
|
+
name: Test
|
|
111
|
+
runs-on: ${{ matrix.os }}
|
|
112
|
+
strategy:
|
|
113
|
+
matrix:
|
|
114
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
115
|
+
node-version: [18, 20, 21]
|
|
116
|
+
exclude:
|
|
117
|
+
# Skip Windows + Node 18 (slow)
|
|
118
|
+
- os: windows-latest
|
|
119
|
+
node-version: 18
|
|
120
|
+
fail-fast: false
|
|
121
|
+
|
|
122
|
+
steps:
|
|
123
|
+
- uses: actions/checkout@v4
|
|
124
|
+
|
|
125
|
+
- name: Setup Node.js ${{ matrix.node-version }}
|
|
126
|
+
uses: actions/setup-node@v4
|
|
127
|
+
with:
|
|
128
|
+
node-version: ${{ matrix.node-version }}
|
|
129
|
+
cache: "npm"
|
|
130
|
+
|
|
131
|
+
- run: npm ci
|
|
132
|
+
- run: npm test
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Advanced Caching
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
- name: Cache dependencies
|
|
139
|
+
uses: actions/cache@v3
|
|
140
|
+
with:
|
|
141
|
+
path: |
|
|
142
|
+
~/.npm
|
|
143
|
+
node_modules
|
|
144
|
+
.next/cache
|
|
145
|
+
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
|
146
|
+
restore-keys: |
|
|
147
|
+
${{ runner.os }}-npm-
|
|
148
|
+
|
|
149
|
+
- name: Cache build
|
|
150
|
+
uses: actions/cache@v3
|
|
151
|
+
with:
|
|
152
|
+
path: |
|
|
153
|
+
dist
|
|
154
|
+
.cache
|
|
155
|
+
key: build-${{ github.sha }}
|
|
156
|
+
restore-keys: |
|
|
157
|
+
build-
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Docker Build & Push
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
docker:
|
|
164
|
+
name: Build & Push Docker
|
|
165
|
+
runs-on: ubuntu-latest
|
|
166
|
+
steps:
|
|
167
|
+
- uses: actions/checkout@v4
|
|
168
|
+
|
|
169
|
+
- name: Set up Docker Buildx
|
|
170
|
+
uses: docker/setup-buildx-action@v3
|
|
171
|
+
|
|
172
|
+
- name: Login to Docker Hub
|
|
173
|
+
uses: docker/login-action@v3
|
|
174
|
+
with:
|
|
175
|
+
username: ${{ secrets.DOCKER_USERNAME }}
|
|
176
|
+
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
177
|
+
|
|
178
|
+
- name: Extract metadata
|
|
179
|
+
id: meta
|
|
180
|
+
uses: docker/metadata-action@v5
|
|
181
|
+
with:
|
|
182
|
+
images: mycompany/myapp
|
|
183
|
+
tags: |
|
|
184
|
+
type=ref,event=branch
|
|
185
|
+
type=ref,event=pr
|
|
186
|
+
type=semver,pattern={{version}}
|
|
187
|
+
type=sha
|
|
188
|
+
|
|
189
|
+
- name: Build and push
|
|
190
|
+
uses: docker/build-push-action@v5
|
|
191
|
+
with:
|
|
192
|
+
context: .
|
|
193
|
+
push: true
|
|
194
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
195
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
196
|
+
cache-from: type=registry,ref=mycompany/myapp:buildcache
|
|
197
|
+
cache-to: type=registry,ref=mycompany/myapp:buildcache,mode=max
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Deployment Workflow
|
|
201
|
+
|
|
202
|
+
```yaml
|
|
203
|
+
# .github/workflows/deploy.yml
|
|
204
|
+
name: Deploy
|
|
205
|
+
|
|
206
|
+
on:
|
|
207
|
+
push:
|
|
208
|
+
branches: [main]
|
|
209
|
+
workflow_dispatch:
|
|
210
|
+
inputs:
|
|
211
|
+
environment:
|
|
212
|
+
description: "Environment to deploy to"
|
|
213
|
+
required: true
|
|
214
|
+
type: choice
|
|
215
|
+
options:
|
|
216
|
+
- staging
|
|
217
|
+
- production
|
|
218
|
+
|
|
219
|
+
jobs:
|
|
220
|
+
deploy:
|
|
221
|
+
name: Deploy to ${{ github.event.inputs.environment || 'staging' }}
|
|
222
|
+
runs-on: ubuntu-latest
|
|
223
|
+
environment:
|
|
224
|
+
name: ${{ github.event.inputs.environment || 'staging' }}
|
|
225
|
+
url: https://${{ steps.deploy.outputs.url }}
|
|
226
|
+
|
|
227
|
+
steps:
|
|
228
|
+
- uses: actions/checkout@v4
|
|
229
|
+
|
|
230
|
+
- name: Download artifacts
|
|
231
|
+
uses: actions/download-artifact@v4
|
|
232
|
+
with:
|
|
233
|
+
name: dist
|
|
234
|
+
path: dist/
|
|
235
|
+
|
|
236
|
+
- name: Deploy to Vercel
|
|
237
|
+
id: deploy
|
|
238
|
+
uses: amondnet/vercel-action@v25
|
|
239
|
+
with:
|
|
240
|
+
vercel-token: ${{ secrets.VERCEL_TOKEN }}
|
|
241
|
+
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
|
|
242
|
+
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
|
|
243
|
+
vercel-args: ${{ github.event.inputs.environment == 'production' && '--prod' || '' }}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Failure Diagnostics
|
|
247
|
+
|
|
248
|
+
```yaml
|
|
249
|
+
- name: Run tests
|
|
250
|
+
id: test
|
|
251
|
+
run: npm test
|
|
252
|
+
continue-on-error: true
|
|
253
|
+
|
|
254
|
+
- name: Upload test results
|
|
255
|
+
if: always()
|
|
256
|
+
uses: actions/upload-artifact@v4
|
|
257
|
+
with:
|
|
258
|
+
name: test-results
|
|
259
|
+
path: |
|
|
260
|
+
test-results/
|
|
261
|
+
coverage/
|
|
262
|
+
|
|
263
|
+
- name: Comment PR with results
|
|
264
|
+
if: failure() && github.event_name == 'pull_request'
|
|
265
|
+
uses: actions/github-script@v7
|
|
266
|
+
with:
|
|
267
|
+
script: |
|
|
268
|
+
github.rest.issues.createComment({
|
|
269
|
+
issue_number: context.issue.number,
|
|
270
|
+
owner: context.repo.owner,
|
|
271
|
+
repo: context.repo.repo,
|
|
272
|
+
body: '❌ Tests failed. Check the [test results](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})'
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
- name: Fail if tests failed
|
|
276
|
+
if: steps.test.outcome == 'failure'
|
|
277
|
+
run: exit 1
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Composite Actions
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
# .github/actions/setup-node/action.yml
|
|
284
|
+
name: "Setup Node.js with Cache"
|
|
285
|
+
description: "Setup Node.js and restore cache"
|
|
286
|
+
|
|
287
|
+
inputs:
|
|
288
|
+
node-version:
|
|
289
|
+
description: "Node.js version"
|
|
290
|
+
required: false
|
|
291
|
+
default: "20"
|
|
292
|
+
|
|
293
|
+
runs:
|
|
294
|
+
using: "composite"
|
|
295
|
+
steps:
|
|
296
|
+
- name: Setup Node.js
|
|
297
|
+
uses: actions/setup-node@v4
|
|
298
|
+
with:
|
|
299
|
+
node-version: ${{ inputs.node-version }}
|
|
300
|
+
cache: "npm"
|
|
301
|
+
|
|
302
|
+
- name: Install dependencies
|
|
303
|
+
shell: bash
|
|
304
|
+
run: npm ci
|
|
305
|
+
# Usage in workflow:
|
|
306
|
+
# - uses: ./.github/actions/setup-node
|
|
307
|
+
# with:
|
|
308
|
+
# node-version: '20'
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Conditional Jobs
|
|
312
|
+
|
|
313
|
+
```yaml
|
|
314
|
+
lint:
|
|
315
|
+
if: github.event_name == 'pull_request'
|
|
316
|
+
runs-on: ubuntu-latest
|
|
317
|
+
steps: [...]
|
|
318
|
+
|
|
319
|
+
deploy:
|
|
320
|
+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
321
|
+
needs: [build, test]
|
|
322
|
+
runs-on: ubuntu-latest
|
|
323
|
+
steps: [...]
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Best Practices
|
|
327
|
+
|
|
328
|
+
1. **Cache dependencies**: Speeds up 3-5x
|
|
329
|
+
2. **Parallel jobs**: Run lint/test/build concurrently
|
|
330
|
+
3. **Matrix strategy**: Test multiple versions/platforms
|
|
331
|
+
4. **Fail fast**: Stop on first failure (or not)
|
|
332
|
+
5. **Upload artifacts**: Debug failures
|
|
333
|
+
6. **Concurrency control**: Cancel outdated runs
|
|
334
|
+
7. **Secrets management**: Never log secrets
|
|
335
|
+
8. **Status checks**: Require passing CI
|
|
336
|
+
|
|
337
|
+
## Output Checklist
|
|
338
|
+
|
|
339
|
+
- [ ] Lint job configured
|
|
340
|
+
- [ ] Test job with coverage
|
|
341
|
+
- [ ] Build job with artifacts
|
|
342
|
+
- [ ] Deploy job with environments
|
|
343
|
+
- [ ] Caching strategy implemented
|
|
344
|
+
- [ ] Matrix builds (if needed)
|
|
345
|
+
- [ ] Failure diagnostics
|
|
346
|
+
- [ ] PR comments on failure
|
|
347
|
+
- [ ] Docker build (if needed)
|
|
348
|
+
- [ ] Status badges in README
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: monorepo-ci-optimizer
|
|
3
|
+
description: Optimizes CI pipelines for monorepos by detecting affected packages/apps and running only necessary builds and tests. Includes Turborepo/Nx strategies, caching, and parallel execution. Use for "monorepo CI", "affected detection", "incremental builds", or "workspace optimization".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Monorepo CI Optimizer
|
|
7
|
+
|
|
8
|
+
Run only affected builds and tests in monorepos for faster CI.
|
|
9
|
+
|
|
10
|
+
## Affected Detection Strategy
|
|
11
|
+
|
|
12
|
+
### Using Turborepo
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
# .github/workflows/ci.yml
|
|
16
|
+
name: CI
|
|
17
|
+
|
|
18
|
+
on:
|
|
19
|
+
pull_request:
|
|
20
|
+
push:
|
|
21
|
+
branches: [main]
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
with:
|
|
29
|
+
fetch-depth: 0 # Need full history for affected detection
|
|
30
|
+
|
|
31
|
+
- uses: actions/setup-node@v4
|
|
32
|
+
with:
|
|
33
|
+
node-version: "20"
|
|
34
|
+
cache: "pnpm"
|
|
35
|
+
|
|
36
|
+
- run: pnpm install
|
|
37
|
+
|
|
38
|
+
- name: Build affected
|
|
39
|
+
run: |
|
|
40
|
+
pnpm turbo run build --filter='...[origin/main]'
|
|
41
|
+
|
|
42
|
+
- name: Test affected
|
|
43
|
+
run: |
|
|
44
|
+
pnpm turbo run test --filter='...[origin/main]'
|
|
45
|
+
|
|
46
|
+
- name: Lint affected
|
|
47
|
+
run: |
|
|
48
|
+
pnpm turbo run lint --filter='...[origin/main]'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Using Nx
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
build:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
with:
|
|
59
|
+
fetch-depth: 0
|
|
60
|
+
|
|
61
|
+
- uses: nrwl/nx-set-shas@v4
|
|
62
|
+
|
|
63
|
+
- uses: actions/setup-node@v4
|
|
64
|
+
with:
|
|
65
|
+
node-version: "20"
|
|
66
|
+
cache: "npm"
|
|
67
|
+
|
|
68
|
+
- run: npm ci
|
|
69
|
+
|
|
70
|
+
- name: Build affected projects
|
|
71
|
+
run: npx nx affected:build --base=$NX_BASE --head=$NX_HEAD
|
|
72
|
+
|
|
73
|
+
- name: Test affected projects
|
|
74
|
+
run: npx nx affected:test --base=$NX_BASE --head=$NX_HEAD --parallel=3
|
|
75
|
+
|
|
76
|
+
- name: Lint affected projects
|
|
77
|
+
run: npx nx affected:lint --base=$NX_BASE --head=$NX_HEAD
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Remote Caching (Turborepo)
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
- name: Setup Turborepo cache
|
|
84
|
+
uses: actions/cache@v3
|
|
85
|
+
with:
|
|
86
|
+
path: .turbo
|
|
87
|
+
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
|
88
|
+
restore-keys: |
|
|
89
|
+
${{ runner.os }}-turbo-
|
|
90
|
+
|
|
91
|
+
- name: Build with remote cache
|
|
92
|
+
run: pnpm turbo run build
|
|
93
|
+
env:
|
|
94
|
+
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
95
|
+
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Nx Cloud Integration
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
- name: Setup Nx Cloud
|
|
102
|
+
run: |
|
|
103
|
+
npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js"
|
|
104
|
+
env:
|
|
105
|
+
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
|
106
|
+
|
|
107
|
+
- name: Run affected
|
|
108
|
+
run: |
|
|
109
|
+
npx nx affected --target=build --parallel=3
|
|
110
|
+
npx nx affected --target=test --parallel=3
|
|
111
|
+
npx nx affected --target=lint --parallel=3
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Manual Affected Detection
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// scripts/get-affected.ts
|
|
118
|
+
import * as path from "path";
|
|
119
|
+
import { execSync } from "child_process";
|
|
120
|
+
import * as fs from "fs";
|
|
121
|
+
|
|
122
|
+
interface Package {
|
|
123
|
+
name: string;
|
|
124
|
+
path: string;
|
|
125
|
+
dependencies: string[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function getChangedFiles(base: string = "origin/main"): string[] {
|
|
129
|
+
const output = execSync(`git diff --name-only ${base}...HEAD`, {
|
|
130
|
+
encoding: "utf-8",
|
|
131
|
+
});
|
|
132
|
+
return output.split("\n").filter(Boolean);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function getPackages(): Package[] {
|
|
136
|
+
const packagesDir = path.join(process.cwd(), "packages");
|
|
137
|
+
return fs.readdirSync(packagesDir).map((name) => {
|
|
138
|
+
const packageJson = JSON.parse(
|
|
139
|
+
fs.readFileSync(path.join(packagesDir, name, "package.json"), "utf-8")
|
|
140
|
+
);
|
|
141
|
+
return {
|
|
142
|
+
name: packageJson.name,
|
|
143
|
+
path: `packages/${name}`,
|
|
144
|
+
dependencies: [
|
|
145
|
+
...Object.keys(packageJson.dependencies || {}),
|
|
146
|
+
...Object.keys(packageJson.devDependencies || {}),
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function getAffectedPackages(): string[] {
|
|
153
|
+
const changedFiles = getChangedFiles();
|
|
154
|
+
const packages = getPackages();
|
|
155
|
+
const affected = new Set<string>();
|
|
156
|
+
|
|
157
|
+
// Direct changes
|
|
158
|
+
changedFiles.forEach((file) => {
|
|
159
|
+
packages.forEach((pkg) => {
|
|
160
|
+
if (file.startsWith(pkg.path)) {
|
|
161
|
+
affected.add(pkg.name);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Dependent packages
|
|
167
|
+
let changed = true;
|
|
168
|
+
while (changed) {
|
|
169
|
+
changed = false;
|
|
170
|
+
packages.forEach((pkg) => {
|
|
171
|
+
if (!affected.has(pkg.name)) {
|
|
172
|
+
const hasAffectedDep = pkg.dependencies.some((dep) =>
|
|
173
|
+
affected.has(dep)
|
|
174
|
+
);
|
|
175
|
+
if (hasAffectedDep) {
|
|
176
|
+
affected.add(pkg.name);
|
|
177
|
+
changed = true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return Array.from(affected);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Output for GitHub Actions
|
|
187
|
+
const affected = getAffectedPackages();
|
|
188
|
+
console.log(`::set-output name=packages::${affected.join(",")}`);
|
|
189
|
+
console.log(`Affected packages: ${affected.join(", ")}`);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Matrix Strategy for Affected Packages
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
detect-affected:
|
|
196
|
+
runs-on: ubuntu-latest
|
|
197
|
+
outputs:
|
|
198
|
+
packages: ${{ steps.affected.outputs.packages }}
|
|
199
|
+
steps:
|
|
200
|
+
- uses: actions/checkout@v4
|
|
201
|
+
with:
|
|
202
|
+
fetch-depth: 0
|
|
203
|
+
|
|
204
|
+
- id: affected
|
|
205
|
+
run: |
|
|
206
|
+
PACKAGES=$(node scripts/get-affected.ts)
|
|
207
|
+
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
|
|
208
|
+
|
|
209
|
+
test-affected:
|
|
210
|
+
needs: detect-affected
|
|
211
|
+
if: needs.detect-affected.outputs.packages != ''
|
|
212
|
+
runs-on: ubuntu-latest
|
|
213
|
+
strategy:
|
|
214
|
+
matrix:
|
|
215
|
+
package: ${{ fromJSON(needs.detect-affected.outputs.packages) }}
|
|
216
|
+
steps:
|
|
217
|
+
- uses: actions/checkout@v4
|
|
218
|
+
|
|
219
|
+
- uses: actions/setup-node@v4
|
|
220
|
+
with:
|
|
221
|
+
node-version: "20"
|
|
222
|
+
cache: "pnpm"
|
|
223
|
+
|
|
224
|
+
- run: pnpm install
|
|
225
|
+
|
|
226
|
+
- name: Test ${{ matrix.package }}
|
|
227
|
+
run: pnpm --filter ${{ matrix.package }} test
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Workspace-aware Caching
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
- name: Cache workspace builds
|
|
234
|
+
uses: actions/cache@v3
|
|
235
|
+
with:
|
|
236
|
+
path: |
|
|
237
|
+
packages/*/dist
|
|
238
|
+
packages/*/node_modules/.cache
|
|
239
|
+
key: ${{ runner.os }}-workspace-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('packages/**/*.ts') }}
|
|
240
|
+
restore-keys: |
|
|
241
|
+
${{ runner.os }}-workspace-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
|
242
|
+
${{ runner.os }}-workspace-
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Parallel Execution
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
- name: Build all packages in parallel
|
|
249
|
+
run: pnpm turbo run build --parallel
|
|
250
|
+
|
|
251
|
+
- name: Test with controlled parallelism
|
|
252
|
+
run: pnpm turbo run test --concurrency=3
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Optimization Metrics
|
|
256
|
+
|
|
257
|
+
```markdown
|
|
258
|
+
## Before Optimization
|
|
259
|
+
|
|
260
|
+
- Full build: 25 minutes
|
|
261
|
+
- All tests: 15 minutes
|
|
262
|
+
- Total: 40 minutes
|
|
263
|
+
- Runs on every PR
|
|
264
|
+
|
|
265
|
+
## After Affected Detection
|
|
266
|
+
|
|
267
|
+
- Affected build: 5 minutes (80% reduction)
|
|
268
|
+
- Affected tests: 3 minutes (80% reduction)
|
|
269
|
+
- Total: 8 minutes (80% reduction)
|
|
270
|
+
- Only runs necessary checks
|
|
271
|
+
|
|
272
|
+
## With Remote Caching
|
|
273
|
+
|
|
274
|
+
- Cache hit build: 30 seconds (98% reduction)
|
|
275
|
+
- Cache hit tests: 1 minute (93% reduction)
|
|
276
|
+
- Total: 1.5 minutes (96% reduction)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Best Practices
|
|
280
|
+
|
|
281
|
+
1. **Fetch full history**: `fetch-depth: 0` for accurate diffs
|
|
282
|
+
2. **Topological order**: Build dependencies first
|
|
283
|
+
3. **Remote caching**: Share cache across CI runs
|
|
284
|
+
4. **Parallel execution**: Run independent tasks concurrently
|
|
285
|
+
5. **Incremental builds**: Only rebuild what changed
|
|
286
|
+
6. **Dependency graph**: Track package relationships
|
|
287
|
+
7. **Force full build**: On main branch merges
|
|
288
|
+
|
|
289
|
+
## Output Checklist
|
|
290
|
+
|
|
291
|
+
- [ ] Affected detection implemented
|
|
292
|
+
- [ ] Turborepo or Nx configured
|
|
293
|
+
- [ ] Remote caching enabled
|
|
294
|
+
- [ ] Parallel execution optimized
|
|
295
|
+
- [ ] Matrix strategy for packages
|
|
296
|
+
- [ ] Workspace-aware caching
|
|
297
|
+
- [ ] Dependency graph documented
|
|
298
|
+
- [ ] Before/after metrics tracked
|