@mmerterden/multi-agent-pipeline 20.36.0 → 20.37.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.
Files changed (191) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/docs/facts.json +1 -1
  3. package/install/catalog-history.json +1 -1
  4. package/manifest.json +194 -122
  5. package/package.json +1 -1
  6. package/pipeline/commands/multi-agent/SKILL.md +33 -154
  7. package/pipeline/commands/multi-agent/analysis/SKILL.md +14 -68
  8. package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +5 -8
  9. package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +38 -109
  10. package/pipeline/commands/multi-agent/channels/SKILL.md +38 -167
  11. package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +37 -144
  12. package/pipeline/commands/multi-agent/design-check/SKILL.md +27 -131
  13. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +22 -48
  14. package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +37 -180
  15. package/pipeline/commands/multi-agent/jira/SKILL.md +16 -46
  16. package/pipeline/commands/multi-agent/refactor/SKILL.md +23 -184
  17. package/pipeline/commands/multi-agent/resume/SKILL.md +30 -136
  18. package/pipeline/commands/multi-agent/review/SKILL.md +24 -199
  19. package/pipeline/commands/multi-agent/setup/SKILL.md +25 -181
  20. package/pipeline/commands/multi-agent/stack/SKILL.md +9 -53
  21. package/pipeline/commands/multi-agent/status/SKILL.md +13 -2
  22. package/pipeline/commands/multi-agent/store-ready/SKILL.md +27 -226
  23. package/pipeline/commands/multi-agent/sync/SKILL.md +35 -164
  24. package/pipeline/commands/multi-agent/test-gen/SKILL.md +2 -4
  25. package/pipeline/commands/multi-agent/update/SKILL.md +18 -60
  26. package/pipeline/contract/CHANGELOG.md +9 -0
  27. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  28. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  29. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  30. package/pipeline/contract/fixtures/runs-awaiting-question.json +1 -1
  31. package/pipeline/contract/fixtures/runs-empty.json +1 -1
  32. package/pipeline/contract/fixtures/runs-failed.json +1 -1
  33. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +1 -1
  34. package/pipeline/contract/fixtures/runs-pr-opened.json +1 -1
  35. package/pipeline/contract/fixtures/runs-running.json +1 -1
  36. package/pipeline/contract/manifest.json +5 -5
  37. package/pipeline/contract/types/index.d.ts +3 -2
  38. package/pipeline/multi-agent-refs/autopilot-on/details.md +148 -0
  39. package/pipeline/multi-agent-refs/channels/generator.md +14 -0
  40. package/pipeline/multi-agent-refs/channels/preview.md +13 -0
  41. package/pipeline/multi-agent-refs/channels/reference.md +46 -0
  42. package/pipeline/multi-agent-refs/complaint-analysis/phases.md +159 -0
  43. package/pipeline/multi-agent-refs/design-check/export.md +1 -0
  44. package/pipeline/multi-agent-refs/design-check/init-inventory.md +1 -1
  45. package/pipeline/multi-agent-refs/design-check/scope-and-ledger.md +64 -0
  46. package/pipeline/multi-agent-refs/features/analysis-command-notes.md +53 -0
  47. package/pipeline/multi-agent-refs/garbage-collect/phases.md +60 -0
  48. package/pipeline/multi-agent-refs/ios-coding-standard/plan.md +71 -0
  49. package/pipeline/multi-agent-refs/ios-coding-standard/resolve-and-scan.md +135 -0
  50. package/pipeline/multi-agent-refs/jira/picker-detail.md +71 -0
  51. package/pipeline/multi-agent-refs/orchestrator/copilot-pipeline.md +88 -0
  52. package/pipeline/multi-agent-refs/orchestrator/dispatcher.md +96 -1
  53. package/pipeline/multi-agent-refs/refactor/sweep.md +190 -0
  54. package/pipeline/multi-agent-refs/resume/details.md +115 -2
  55. package/pipeline/multi-agent-refs/review/inputs.md +33 -1
  56. package/pipeline/multi-agent-refs/review/module-guides.md +9 -1
  57. package/pipeline/multi-agent-refs/review/panel.md +75 -0
  58. package/pipeline/multi-agent-refs/review/valven.md +5 -1
  59. package/pipeline/multi-agent-refs/setup/hooks-and-plugins.md +4 -0
  60. package/pipeline/multi-agent-refs/setup/token-save-flow.md +13 -0
  61. package/pipeline/multi-agent-refs/stack/background.md +72 -0
  62. package/pipeline/multi-agent-refs/store-ready/gates.md +139 -0
  63. package/pipeline/multi-agent-refs/store-ready/report.md +40 -2
  64. package/pipeline/multi-agent-refs/sync/office.md +10 -0
  65. package/pipeline/multi-agent-refs/sync/overview.md +61 -0
  66. package/pipeline/multi-agent-refs/sync/repo.md +91 -0
  67. package/pipeline/multi-agent-refs/update/details.md +83 -0
  68. package/pipeline/schemas/runs-index.schema.json +2 -1
  69. package/pipeline/scripts/contract-server.mjs +1 -1
  70. package/pipeline/scripts/runs-index.mjs +34 -7
  71. package/pipeline/scripts/status-overview.mjs +401 -0
  72. package/pipeline/skills/.skill-manifest.json +63 -63
  73. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +7 -70
  74. package/pipeline/skills/shared/core/apple-archive-compliance/references/examples.md +67 -0
  75. package/pipeline/skills/shared/core/apple-archive-compliance/references/version-history.md +8 -0
  76. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +10 -72
  77. package/pipeline/skills/shared/core/google-play-compliance/references/examples.md +69 -0
  78. package/pipeline/skills/shared/core/google-play-compliance/references/notes.md +7 -0
  79. package/pipeline/skills/shared/core/google-play-compliance/references/version-history.md +5 -0
  80. package/pipeline/skills/shared/core/multi-agent/SKILL.md +39 -262
  81. package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +35 -73
  82. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +37 -337
  83. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +27 -122
  84. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +8 -340
  85. package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +37 -180
  86. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +23 -184
  87. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +14 -82
  88. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +25 -277
  89. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +13 -2
  90. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +73 -217
  91. package/pipeline/skills/shared/external/alarmkit/SKILL.md +11 -162
  92. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-code.md +257 -0
  93. package/pipeline/skills/shared/external/android-architecture/SKILL.md +7 -58
  94. package/pipeline/skills/shared/external/android-architecture/references/code-examples.md +68 -0
  95. package/pipeline/skills/shared/external/app-intents/SKILL.md +3 -45
  96. package/pipeline/skills/shared/external/app-intents/references/code-examples.md +54 -0
  97. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +5 -81
  98. package/pipeline/skills/shared/external/app-store-optimization/references/engagement-and-localization.md +96 -0
  99. package/pipeline/skills/shared/external/app-store-review/SKILL.md +6 -112
  100. package/pipeline/skills/shared/external/app-store-review/references/monetization-and-submission.md +138 -0
  101. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +10 -117
  102. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models-code.md +186 -0
  103. package/pipeline/skills/shared/external/authentication/SKILL.md +3 -50
  104. package/pipeline/skills/shared/external/authentication/references/code-examples.md +59 -0
  105. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +3 -84
  106. package/pipeline/skills/shared/external/callkit-voip/references/code-examples.md +93 -0
  107. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +7 -263
  108. package/pipeline/skills/shared/external/ci-cd-pipelines/references/pipeline-examples.md +281 -0
  109. package/pipeline/skills/shared/external/clean-code/SKILL.md +8 -41
  110. package/pipeline/skills/shared/external/clean-code/references/code-examples.md +56 -0
  111. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +8 -146
  112. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-code.md +214 -0
  113. package/pipeline/skills/shared/external/compose-components/SKILL.md +6 -80
  114. package/pipeline/skills/shared/external/compose-components/references/code-examples.md +89 -0
  115. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +5 -64
  116. package/pipeline/skills/shared/external/compose-navigation/references/code-examples.md +70 -0
  117. package/pipeline/skills/shared/external/core-data/SKILL.md +9 -157
  118. package/pipeline/skills/shared/external/core-data/references/core-data-code.md +221 -0
  119. package/pipeline/skills/shared/external/core-nfc/SKILL.md +3 -89
  120. package/pipeline/skills/shared/external/core-nfc/references/code-examples.md +98 -0
  121. package/pipeline/skills/shared/external/coreml/SKILL.md +17 -133
  122. package/pipeline/skills/shared/external/coreml/references/coreml-code.md +208 -0
  123. package/pipeline/skills/shared/external/css-modern/SKILL.md +8 -131
  124. package/pipeline/skills/shared/external/css-modern/references/code-examples.md +142 -0
  125. package/pipeline/skills/shared/external/database-patterns/SKILL.md +6 -103
  126. package/pipeline/skills/shared/external/database-patterns/references/orm-examples.md +112 -0
  127. package/pipeline/skills/shared/external/html-semantic/SKILL.md +7 -48
  128. package/pipeline/skills/shared/external/html-semantic/references/code-examples.md +54 -0
  129. package/pipeline/skills/shared/external/humanizer/SKILL.md +6 -19
  130. package/pipeline/skills/shared/external/humanizer/references/voice.md +24 -0
  131. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +13 -170
  132. package/pipeline/skills/shared/external/ios-accessibility/references/assistive-tech-review.md +224 -0
  133. package/pipeline/skills/shared/external/ios-localization/SKILL.md +2 -24
  134. package/pipeline/skills/shared/external/ios-localization/references/code-examples.md +30 -0
  135. package/pipeline/skills/shared/external/ios-networking/SKILL.md +3 -58
  136. package/pipeline/skills/shared/external/ios-networking/references/code-examples.md +67 -0
  137. package/pipeline/skills/shared/external/ios-security/SKILL.md +4 -64
  138. package/pipeline/skills/shared/external/ios-security/references/code-examples.md +74 -0
  139. package/pipeline/skills/shared/external/live-activities/SKILL.md +4 -90
  140. package/pipeline/skills/shared/external/live-activities/references/code-examples.md +108 -0
  141. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +9 -23
  142. package/pipeline/skills/shared/external/localization-reuse-map/references/project-settings.md +22 -0
  143. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +5 -95
  144. package/pipeline/skills/shared/external/mapkit-location/references/code-examples.md +117 -0
  145. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +7 -106
  146. package/pipeline/skills/shared/external/nextjs-app-router/references/app-router-examples.md +124 -0
  147. package/pipeline/skills/shared/external/permissionkit/SKILL.md +2 -31
  148. package/pipeline/skills/shared/external/permissionkit/references/code-examples.md +37 -0
  149. package/pipeline/skills/shared/external/play-store-review/SKILL.md +6 -74
  150. package/pipeline/skills/shared/external/play-store-review/references/signing-and-policies.md +83 -0
  151. package/pipeline/skills/shared/external/push-notifications/SKILL.md +8 -125
  152. package/pipeline/skills/shared/external/push-notifications/references/notification-code.md +176 -0
  153. package/pipeline/skills/shared/external/python-patterns/SKILL.md +7 -158
  154. package/pipeline/skills/shared/external/python-patterns/references/python-examples.md +176 -0
  155. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +7 -157
  156. package/pipeline/skills/shared/external/rest-api-design/references/api-examples.md +175 -0
  157. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +11 -230
  158. package/pipeline/skills/shared/external/swift-architecture/references/pattern-examples.md +295 -0
  159. package/pipeline/skills/shared/external/swift-codable/SKILL.md +17 -149
  160. package/pipeline/skills/shared/external/swift-codable/references/codable-recipes.md +207 -0
  161. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +12 -99
  162. package/pipeline/skills/shared/external/swift-concurrency/references/code-examples.md +100 -0
  163. package/pipeline/skills/shared/external/swift-concurrency/references/swift-6-2-additions.md +18 -0
  164. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +9 -78
  165. package/pipeline/skills/shared/external/swift-formatstyle/references/formatstyle-examples.md +113 -0
  166. package/pipeline/skills/shared/external/swift-language/SKILL.md +3 -56
  167. package/pipeline/skills/shared/external/swift-language/references/code-examples.md +65 -0
  168. package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +1 -0
  169. package/pipeline/skills/shared/external/swiftdata/SKILL.md +6 -122
  170. package/pipeline/skills/shared/external/swiftdata/references/code-examples.md +140 -0
  171. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +12 -139
  172. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/interop-code.md +198 -0
  173. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +9 -81
  174. package/pipeline/skills/shared/external/tailwind-css/references/code-examples.md +91 -0
  175. package/pipeline/skills/shared/external/testing-backend/SKILL.md +7 -207
  176. package/pipeline/skills/shared/external/testing-backend/references/testing-examples.md +225 -0
  177. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +8 -89
  178. package/pipeline/skills/shared/external/typescript-patterns/references/code-examples.md +100 -0
  179. package/pipeline/skills/shared/external/vision-framework/SKILL.md +2 -20
  180. package/pipeline/skills/shared/external/vision-framework/references/code-examples.md +26 -0
  181. package/pipeline/skills/shared/external/vue-composition/SKILL.md +7 -169
  182. package/pipeline/skills/shared/external/vue-composition/references/vue-examples.md +187 -0
  183. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +7 -174
  184. package/pipeline/skills/shared/external/web-accessibility/references/a11y-examples.md +192 -0
  185. package/pipeline/skills/shared/external/web-performance/SKILL.md +8 -66
  186. package/pipeline/skills/shared/external/web-performance/references/code-examples.md +77 -0
  187. package/pipeline/skills/shared/external/web-testing/SKILL.md +11 -186
  188. package/pipeline/skills/shared/external/web-testing/references/testing-examples.md +213 -0
  189. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/format-and-output.md +0 -0
  190. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/publish-and-snapshot.md +0 -0
  191. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/sources-and-recipes.md +0 -0
@@ -19,275 +19,15 @@ for all pipeline definitions.
19
19
 
20
20
  ### Full CI Pipeline
21
21
 
22
- ```yaml
23
- # .github/workflows/ci.yml
24
- name: CI
25
-
26
- on:
27
- push:
28
- branches: [main]
29
- pull_request:
30
- branches: [main]
31
-
32
- concurrency:
33
- group: ${{ github.workflow }}-${{ github.ref }}
34
- cancel-in-progress: true
35
-
36
- env:
37
- NODE_VERSION: '22'
38
- REGISTRY: ghcr.io
39
- IMAGE_NAME: ${{ github.repository }}
40
-
41
- jobs:
42
- lint:
43
- runs-on: ubuntu-latest
44
- steps:
45
- - uses: actions/checkout@v4
46
-
47
- - uses: actions/setup-node@v4
48
- with:
49
- node-version: ${{ env.NODE_VERSION }}
50
- cache: 'npm'
51
-
52
- - run: npm ci
53
-
54
- - name: Lint
55
- run: npm run lint
56
-
57
- - name: Type check
58
- run: npm run type-check
59
-
60
- test:
61
- runs-on: ubuntu-latest
62
- needs: lint
63
-
64
- services:
65
- postgres:
66
- image: postgres:16
67
- env:
68
- POSTGRES_USER: test
69
- POSTGRES_PASSWORD: test
70
- POSTGRES_DB: test_db
71
- ports:
72
- - 5432:5432
73
- options: >-
74
- --health-cmd pg_isready
75
- --health-interval 10s
76
- --health-timeout 5s
77
- --health-retries 5
78
-
79
- redis:
80
- image: redis:7
81
- ports:
82
- - 6379:6379
83
-
84
- steps:
85
- - uses: actions/checkout@v4
86
-
87
- - uses: actions/setup-node@v4
88
- with:
89
- node-version: ${{ env.NODE_VERSION }}
90
- cache: 'npm'
91
-
92
- - run: npm ci
93
-
94
- - name: Run migrations
95
- run: npx prisma migrate deploy
96
- env:
97
- DATABASE_URL: postgresql://test:test@localhost:5432/test_db
98
-
99
- - name: Run tests
100
- run: npm test -- --coverage
101
- env:
102
- DATABASE_URL: postgresql://test:test@localhost:5432/test_db
103
- REDIS_URL: redis://localhost:6379
104
-
105
- - name: Upload coverage
106
- if: github.event_name == 'pull_request'
107
- uses: codecov/codecov-action@v4
108
- with:
109
- token: ${{ secrets.CODECOV_TOKEN }}
110
-
111
- e2e:
112
- runs-on: ubuntu-latest
113
- needs: test
114
- steps:
115
- - uses: actions/checkout@v4
116
-
117
- - uses: actions/setup-node@v4
118
- with:
119
- node-version: ${{ env.NODE_VERSION }}
120
- cache: 'npm'
121
-
122
- - run: npm ci
123
-
124
- - name: Install Playwright browsers
125
- run: npx playwright install --with-deps chromium
126
-
127
- - name: Run E2E tests
128
- run: npx playwright test
129
- env:
130
- BASE_URL: http://localhost:3000
131
-
132
- - name: Upload test results
133
- if: failure()
134
- uses: actions/upload-artifact@v4
135
- with:
136
- name: playwright-report
137
- path: playwright-report/
138
-
139
- build:
140
- runs-on: ubuntu-latest
141
- needs: [test, e2e]
142
- if: github.ref == 'refs/heads/main'
143
- permissions:
144
- contents: read
145
- packages: write
146
-
147
- steps:
148
- - uses: actions/checkout@v4
149
-
150
- - name: Log in to Container Registry
151
- uses: docker/login-action@v3
152
- with:
153
- registry: ${{ env.REGISTRY }}
154
- username: ${{ github.actor }}
155
- password: ${{ secrets.GITHUB_TOKEN }}
156
-
157
- - name: Extract metadata
158
- id: meta
159
- uses: docker/metadata-action@v5
160
- with:
161
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
162
- tags: |
163
- type=sha
164
- type=ref,event=branch
165
- type=semver,pattern={{version}}
166
-
167
- - name: Build and push
168
- uses: docker/build-push-action@v5
169
- with:
170
- context: .
171
- push: true
172
- tags: ${{ steps.meta.outputs.tags }}
173
- labels: ${{ steps.meta.outputs.labels }}
174
- cache-from: type=gha
175
- cache-to: type=gha,mode=max
176
- ```
22
+ Code for this section: [CI/CD pipeline examples](references/pipeline-examples.md).
177
23
 
178
24
  ### Deploy Workflow
179
25
 
180
- ```yaml
181
- # .github/workflows/deploy.yml
182
- name: Deploy
183
-
184
- on:
185
- workflow_run:
186
- workflows: [CI]
187
- types: [completed]
188
- branches: [main]
189
-
190
- jobs:
191
- deploy-staging:
192
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
193
- runs-on: ubuntu-latest
194
- environment: staging
195
-
196
- steps:
197
- - uses: actions/checkout@v4
198
-
199
- - name: Deploy to staging
200
- run: |
201
- echo "Deploying to staging..."
202
- # Use your deployment tool
203
- env:
204
- DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
205
- DEPLOY_URL: ${{ vars.STAGING_URL }}
206
-
207
- - name: Run smoke tests
208
- run: |
209
- curl --fail --retry 5 --retry-delay 10 "${{ vars.STAGING_URL }}/health"
210
-
211
- deploy-production:
212
- needs: deploy-staging
213
- runs-on: ubuntu-latest
214
- environment: production
215
-
216
- steps:
217
- - uses: actions/checkout@v4
218
-
219
- - name: Deploy to production
220
- run: |
221
- echo "Deploying to production..."
222
- env:
223
- DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
224
- DEPLOY_URL: ${{ vars.PRODUCTION_URL }}
225
-
226
- - name: Verify deployment
227
- run: |
228
- curl --fail --retry 5 --retry-delay 10 "${{ vars.PRODUCTION_URL }}/health"
229
- ```
26
+ Code for this section: [CI/CD pipeline examples](references/pipeline-examples.md).
230
27
 
231
28
  ## Docker Multi-Stage Builds
232
29
 
233
- ```dockerfile
234
- # Dockerfile
235
- # Stage 1: Dependencies
236
- FROM node:22-alpine AS deps
237
- WORKDIR /app
238
- COPY package.json package-lock.json ./
239
- RUN npm ci --production=false
240
-
241
- # Stage 2: Build
242
- FROM node:22-alpine AS builder
243
- WORKDIR /app
244
- COPY --from=deps /app/node_modules ./node_modules
245
- COPY . .
246
- RUN npm run build
247
- RUN npm prune --production
248
-
249
- # Stage 3: Production
250
- FROM node:22-alpine AS runner
251
- WORKDIR /app
252
-
253
- # Security: non-root user
254
- RUN addgroup --system app && adduser --system --ingroup app app
255
-
256
- # Copy only what's needed
257
- COPY --from=builder --chown=app:app /app/dist ./dist
258
- COPY --from=builder --chown=app:app /app/node_modules ./node_modules
259
- COPY --from=builder --chown=app:app /app/package.json ./
260
-
261
- USER app
262
- EXPOSE 3000
263
-
264
- ENV NODE_ENV=production
265
- ENV PORT=3000
266
-
267
- HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
268
- CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
269
-
270
- CMD ["node", "dist/server.js"]
271
- ```
272
-
273
- ```dockerfile
274
- # Python multi-stage
275
- FROM python:3.12-slim AS builder
276
- WORKDIR /app
277
- RUN pip install --no-cache-dir poetry
278
- COPY pyproject.toml poetry.lock ./
279
- RUN poetry export -f requirements.txt -o requirements.txt --without-hashes
280
- RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
281
-
282
- FROM python:3.12-slim AS runner
283
- WORKDIR /app
284
- RUN useradd --system app
285
- COPY --from=builder /install /usr/local
286
- COPY . .
287
- USER app
288
- EXPOSE 8000
289
- CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
290
- ```
30
+ Code for this section: [CI/CD pipeline examples](references/pipeline-examples.md).
291
31
 
292
32
  ## Environment Management
293
33
 
@@ -463,3 +203,7 @@ async function handleRequest(req: Request) {
463
203
  | Secret not available | Wrong scope or missing secret | Check repository vs environment secrets; verify name |
464
204
  | Deploy succeeds but app crashes | Missing env vars in production | Validate env at startup, check deployment config |
465
205
  | Rollback needed | Bad deploy passed health checks | Improve health checks, add smoke tests, use canary |
206
+
207
+ ## References
208
+
209
+ - [CI/CD pipeline examples](references/pipeline-examples.md): open when writing a full CI workflow, a deploy workflow or a multi-stage Docker build.
@@ -0,0 +1,281 @@
1
+ # CI/CD pipeline examples
2
+
3
+ <!-- toc -->
4
+ - [Full CI Pipeline](#full-ci-pipeline)
5
+ - [Deploy Workflow](#deploy-workflow)
6
+ - [Docker Multi-Stage Builds](#docker-multi-stage-builds)
7
+ <!-- /toc -->
8
+
9
+ Complete GitHub Actions CI and deploy workflows and a multi-stage Dockerfile. SKILL.md keeps the principles, environment and secret rules, and deployment strategies.
10
+
11
+ ## Full CI Pipeline
12
+
13
+ ```yaml
14
+ # .github/workflows/ci.yml
15
+ name: CI
16
+
17
+ on:
18
+ push:
19
+ branches: [main]
20
+ pull_request:
21
+ branches: [main]
22
+
23
+ concurrency:
24
+ group: ${{ github.workflow }}-${{ github.ref }}
25
+ cancel-in-progress: true
26
+
27
+ env:
28
+ NODE_VERSION: '22'
29
+ REGISTRY: ghcr.io
30
+ IMAGE_NAME: ${{ github.repository }}
31
+
32
+ jobs:
33
+ lint:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - uses: actions/setup-node@v4
39
+ with:
40
+ node-version: ${{ env.NODE_VERSION }}
41
+ cache: 'npm'
42
+
43
+ - run: npm ci
44
+
45
+ - name: Lint
46
+ run: npm run lint
47
+
48
+ - name: Type check
49
+ run: npm run type-check
50
+
51
+ test:
52
+ runs-on: ubuntu-latest
53
+ needs: lint
54
+
55
+ services:
56
+ postgres:
57
+ image: postgres:16
58
+ env:
59
+ POSTGRES_USER: test
60
+ POSTGRES_PASSWORD: test
61
+ POSTGRES_DB: test_db
62
+ ports:
63
+ - 5432:5432
64
+ options: >-
65
+ --health-cmd pg_isready
66
+ --health-interval 10s
67
+ --health-timeout 5s
68
+ --health-retries 5
69
+
70
+ redis:
71
+ image: redis:7
72
+ ports:
73
+ - 6379:6379
74
+
75
+ steps:
76
+ - uses: actions/checkout@v4
77
+
78
+ - uses: actions/setup-node@v4
79
+ with:
80
+ node-version: ${{ env.NODE_VERSION }}
81
+ cache: 'npm'
82
+
83
+ - run: npm ci
84
+
85
+ - name: Run migrations
86
+ run: npx prisma migrate deploy
87
+ env:
88
+ DATABASE_URL: postgresql://test:test@localhost:5432/test_db
89
+
90
+ - name: Run tests
91
+ run: npm test -- --coverage
92
+ env:
93
+ DATABASE_URL: postgresql://test:test@localhost:5432/test_db
94
+ REDIS_URL: redis://localhost:6379
95
+
96
+ - name: Upload coverage
97
+ if: github.event_name == 'pull_request'
98
+ uses: codecov/codecov-action@v4
99
+ with:
100
+ token: ${{ secrets.CODECOV_TOKEN }}
101
+
102
+ e2e:
103
+ runs-on: ubuntu-latest
104
+ needs: test
105
+ steps:
106
+ - uses: actions/checkout@v4
107
+
108
+ - uses: actions/setup-node@v4
109
+ with:
110
+ node-version: ${{ env.NODE_VERSION }}
111
+ cache: 'npm'
112
+
113
+ - run: npm ci
114
+
115
+ - name: Install Playwright browsers
116
+ run: npx playwright install --with-deps chromium
117
+
118
+ - name: Run E2E tests
119
+ run: npx playwright test
120
+ env:
121
+ BASE_URL: http://localhost:3000
122
+
123
+ - name: Upload test results
124
+ if: failure()
125
+ uses: actions/upload-artifact@v4
126
+ with:
127
+ name: playwright-report
128
+ path: playwright-report/
129
+
130
+ build:
131
+ runs-on: ubuntu-latest
132
+ needs: [test, e2e]
133
+ if: github.ref == 'refs/heads/main'
134
+ permissions:
135
+ contents: read
136
+ packages: write
137
+
138
+ steps:
139
+ - uses: actions/checkout@v4
140
+
141
+ - name: Log in to Container Registry
142
+ uses: docker/login-action@v3
143
+ with:
144
+ registry: ${{ env.REGISTRY }}
145
+ username: ${{ github.actor }}
146
+ password: ${{ secrets.GITHUB_TOKEN }}
147
+
148
+ - name: Extract metadata
149
+ id: meta
150
+ uses: docker/metadata-action@v5
151
+ with:
152
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
153
+ tags: |
154
+ type=sha
155
+ type=ref,event=branch
156
+ type=semver,pattern={{version}}
157
+
158
+ - name: Build and push
159
+ uses: docker/build-push-action@v5
160
+ with:
161
+ context: .
162
+ push: true
163
+ tags: ${{ steps.meta.outputs.tags }}
164
+ labels: ${{ steps.meta.outputs.labels }}
165
+ cache-from: type=gha
166
+ cache-to: type=gha,mode=max
167
+ ```
168
+
169
+ ## Deploy Workflow
170
+
171
+ ```yaml
172
+ # .github/workflows/deploy.yml
173
+ name: Deploy
174
+
175
+ on:
176
+ workflow_run:
177
+ workflows: [CI]
178
+ types: [completed]
179
+ branches: [main]
180
+
181
+ jobs:
182
+ deploy-staging:
183
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
184
+ runs-on: ubuntu-latest
185
+ environment: staging
186
+
187
+ steps:
188
+ - uses: actions/checkout@v4
189
+
190
+ - name: Deploy to staging
191
+ run: |
192
+ echo "Deploying to staging..."
193
+ # Use your deployment tool
194
+ env:
195
+ DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
196
+ DEPLOY_URL: ${{ vars.STAGING_URL }}
197
+
198
+ - name: Run smoke tests
199
+ run: |
200
+ curl --fail --retry 5 --retry-delay 10 "${{ vars.STAGING_URL }}/health"
201
+
202
+ deploy-production:
203
+ needs: deploy-staging
204
+ runs-on: ubuntu-latest
205
+ environment: production
206
+
207
+ steps:
208
+ - uses: actions/checkout@v4
209
+
210
+ - name: Deploy to production
211
+ run: |
212
+ echo "Deploying to production..."
213
+ env:
214
+ DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
215
+ DEPLOY_URL: ${{ vars.PRODUCTION_URL }}
216
+
217
+ - name: Verify deployment
218
+ run: |
219
+ curl --fail --retry 5 --retry-delay 10 "${{ vars.PRODUCTION_URL }}/health"
220
+ ```
221
+
222
+ ## Docker Multi-Stage Builds
223
+
224
+ ```dockerfile
225
+ # Dockerfile
226
+ # Stage 1: Dependencies
227
+ FROM node:22-alpine AS deps
228
+ WORKDIR /app
229
+ COPY package.json package-lock.json ./
230
+ RUN npm ci --production=false
231
+
232
+ # Stage 2: Build
233
+ FROM node:22-alpine AS builder
234
+ WORKDIR /app
235
+ COPY --from=deps /app/node_modules ./node_modules
236
+ COPY . .
237
+ RUN npm run build
238
+ RUN npm prune --production
239
+
240
+ # Stage 3: Production
241
+ FROM node:22-alpine AS runner
242
+ WORKDIR /app
243
+
244
+ # Security: non-root user
245
+ RUN addgroup --system app && adduser --system --ingroup app app
246
+
247
+ # Copy only what's needed
248
+ COPY --from=builder --chown=app:app /app/dist ./dist
249
+ COPY --from=builder --chown=app:app /app/node_modules ./node_modules
250
+ COPY --from=builder --chown=app:app /app/package.json ./
251
+
252
+ USER app
253
+ EXPOSE 3000
254
+
255
+ ENV NODE_ENV=production
256
+ ENV PORT=3000
257
+
258
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
259
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
260
+
261
+ CMD ["node", "dist/server.js"]
262
+ ```
263
+
264
+ ```dockerfile
265
+ # Python multi-stage
266
+ FROM python:3.12-slim AS builder
267
+ WORKDIR /app
268
+ RUN pip install --no-cache-dir poetry
269
+ COPY pyproject.toml poetry.lock ./
270
+ RUN poetry export -f requirements.txt -o requirements.txt --without-hashes
271
+ RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
272
+
273
+ FROM python:3.12-slim AS runner
274
+ WORKDIR /app
275
+ RUN useradd --system app
276
+ COPY --from=builder /install /usr/local
277
+ COPY . .
278
+ USER app
279
+ EXPOSE 8000
280
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
281
+ ```
@@ -46,15 +46,7 @@ a tidy body behind a misleading name, because callers only ever see the name.
46
46
  - Length follows scope: `i` is fine in a three-line loop; a module-level value
47
47
  needs a full phrase.
48
48
 
49
- ```python
50
- # Before
51
- def calc(d, f):
52
- return d * (1 - f)
53
-
54
- # After
55
- def discounted_price(list_price: Decimal, discount_rate: Decimal) -> Decimal:
56
- return list_price * (1 - discount_rate)
57
- ```
49
+ Code: [1. Names](references/code-examples.md#1-names).
58
50
 
59
51
  ## 2. Units of work
60
52
 
@@ -66,14 +58,7 @@ def discounted_price(list_price: Decimal, discount_rate: Decimal) -> Decimal:
66
58
  usually means a missing type or two functions sharing a name.
67
59
  - A body longer than a screen is a prompt to look for the seams, not a rule.
68
60
 
69
- ```swift
70
- // Before: the flag hides two behaviours
71
- func export(_ report: Report, asPDF: Bool) -> Data
72
-
73
- // After: two names, no flag
74
- func exportPDF(_ report: Report) -> Data
75
- func exportCSV(_ report: Report) -> Data
76
- ```
61
+ Code: [2. Units of work](references/code-examples.md#2-units-of-work).
77
62
 
78
63
  ## 3. Control flow
79
64
 
@@ -85,23 +70,7 @@ func exportCSV(_ report: Report) -> Data
85
70
  better than the raw expression inside an `if`.
86
71
  - Nesting past two levels almost always hides a function waiting to be extracted.
87
72
 
88
- ```typescript
89
- // Before
90
- function shippingCost(order: Order): number {
91
- if (order.items.length > 0) {
92
- if (!order.isDigital) {
93
- return order.weightKg * RATE_PER_KG;
94
- }
95
- }
96
- return 0;
97
- }
98
-
99
- // After
100
- function shippingCost(order: Order): number {
101
- if (order.items.length === 0 || order.isDigital) return 0;
102
- return order.weightKg * RATE_PER_KG;
103
- }
104
- ```
73
+ Code: [3. Control flow](references/code-examples.md#3-control-flow).
105
74
 
106
75
  ## 4. State and side effects
107
76
 
@@ -124,13 +93,7 @@ function shippingCost(order: Order): number {
124
93
  - Check the boundaries every time: empty input, one element, the maximum, and
125
94
  values that are present but invalid.
126
95
 
127
- ```kotlin
128
- // Before: the caller cannot tell "not found" from "zero"
129
- fun itemCount(orderId: String): Int = repository.find(orderId)?.items ?: 0
130
-
131
- // After
132
- fun itemCount(orderId: String): Int? = repository.find(orderId)?.items
133
- ```
96
+ Code: [5. Errors and edge values](references/code-examples.md#5-errors-and-edge-values).
134
97
 
135
98
  ## 6. Comments
136
99
 
@@ -194,3 +157,7 @@ Leave formatting to the formatter and say nothing about it.
194
157
  - Speed and memory: profile first, then use the stack's performance skill.
195
158
  - Module boundaries and system design: use `architecture`.
196
159
  - Language style rules a linter enforces: follow the linter.
160
+
161
+ ## References
162
+
163
+ - [Code examples](references/code-examples.md): open for the full code behind 1. Names, 2. Units of work, 3. Control flow, 5. Errors and edge values.
@@ -0,0 +1,56 @@
1
+ # Clean Code Code Examples
2
+
3
+ Full code samples for the SKILL.md sections that link here. The rules and the decision guidance stay in SKILL.md; each heading below matches the SKILL.md section the code belongs to.
4
+
5
+ ## 1. Names
6
+
7
+ ```python
8
+ # Before
9
+ def calc(d, f):
10
+ return d * (1 - f)
11
+
12
+ # After
13
+ def discounted_price(list_price: Decimal, discount_rate: Decimal) -> Decimal:
14
+ return list_price * (1 - discount_rate)
15
+ ```
16
+
17
+ ## 2. Units of work
18
+
19
+ ```swift
20
+ // Before: the flag hides two behaviours
21
+ func export(_ report: Report, asPDF: Bool) -> Data
22
+
23
+ // After: two names, no flag
24
+ func exportPDF(_ report: Report) -> Data
25
+ func exportCSV(_ report: Report) -> Data
26
+ ```
27
+
28
+ ## 3. Control flow
29
+
30
+ ```typescript
31
+ // Before
32
+ function shippingCost(order: Order): number {
33
+ if (order.items.length > 0) {
34
+ if (!order.isDigital) {
35
+ return order.weightKg * RATE_PER_KG;
36
+ }
37
+ }
38
+ return 0;
39
+ }
40
+
41
+ // After
42
+ function shippingCost(order: Order): number {
43
+ if (order.items.length === 0 || order.isDigital) return 0;
44
+ return order.weightKg * RATE_PER_KG;
45
+ }
46
+ ```
47
+
48
+ ## 5. Errors and edge values
49
+
50
+ ```kotlin
51
+ // Before: the caller cannot tell "not found" from "zero"
52
+ fun itemCount(orderId: String): Int = repository.find(orderId)?.items ?: 0
53
+
54
+ // After
55
+ fun itemCount(orderId: String): Int? = repository.find(orderId)?.items
56
+ ```