agileflow 2.33.1 → 2.35.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/LICENSE +22 -0
- package/README.md +536 -0
- package/package.json +1 -1
- package/src/core/agents/adr-writer.md +3 -19
- package/src/core/agents/api.md +9 -43
- package/src/core/agents/ci.md +8 -40
- package/src/core/agents/configuration/archival.md +301 -0
- package/src/core/agents/configuration/attribution.md +318 -0
- package/src/core/agents/configuration/ci.md +1077 -0
- package/src/core/agents/configuration/git-config.md +511 -0
- package/src/core/agents/configuration/hooks.md +507 -0
- package/src/core/agents/configuration/verify.md +540 -0
- package/src/core/agents/devops.md +7 -35
- package/src/core/agents/documentation.md +0 -1
- package/src/core/agents/epic-planner.md +3 -22
- package/src/core/agents/mentor.md +8 -24
- package/src/core/agents/research.md +0 -7
- package/src/core/agents/security.md +0 -5
- package/src/core/agents/ui.md +8 -42
- package/src/core/commands/PATTERNS-AskUserQuestion.md +474 -0
- package/src/core/commands/adr.md +5 -0
- package/src/core/commands/agent.md +4 -0
- package/src/core/commands/assign.md +1 -0
- package/src/core/commands/auto.md +1 -1
- package/src/core/commands/babysit.md +147 -31
- package/src/core/commands/baseline.md +7 -0
- package/src/core/commands/blockers.md +2 -0
- package/src/core/commands/board.md +9 -0
- package/src/core/commands/configure.md +415 -0
- package/src/core/commands/context.md +1 -0
- package/src/core/commands/deps.md +2 -0
- package/src/core/commands/diagnose.md +0 -41
- package/src/core/commands/epic.md +8 -0
- package/src/core/commands/handoff.md +4 -0
- package/src/core/commands/impact.md +1 -1
- package/src/core/commands/metrics.md +10 -0
- package/src/core/commands/research.md +3 -0
- package/src/core/commands/retro.md +11 -1
- package/src/core/commands/sprint.md +2 -1
- package/src/core/commands/status.md +1 -0
- package/src/core/commands/story-validate.md +1 -1
- package/src/core/commands/story.md +29 -2
- package/src/core/commands/template.md +8 -0
- package/src/core/commands/update.md +1 -1
- package/src/core/commands/velocity.md +9 -0
- package/src/core/commands/verify.md +6 -0
- package/src/core/templates/validate-tokens.sh +0 -15
- package/src/core/templates/worktrees-guide.md +0 -4
- package/tools/agileflow-npx.js +21 -9
- package/tools/cli/commands/config.js +284 -0
- package/tools/cli/commands/doctor.js +221 -4
- package/tools/cli/commands/setup.js +4 -1
- package/tools/cli/commands/update.js +59 -15
- package/tools/cli/installers/core/installer.js +369 -37
- package/tools/cli/installers/ide/claude-code.js +1 -1
- package/tools/cli/installers/ide/cursor.js +1 -1
- package/tools/cli/installers/ide/windsurf.js +1 -1
- package/tools/cli/lib/docs-setup.js +52 -28
- package/tools/cli/lib/npm-utils.js +62 -0
- package/tools/cli/lib/ui.js +9 -2
- package/tools/postinstall.js +71 -13
- package/src/core/agents/context7.md +0 -164
- package/src/core/commands/setup.md +0 -708
|
@@ -0,0 +1,1077 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configuration-ci
|
|
3
|
+
description: Configure CI/CD workflow for automated testing and quality checks
|
|
4
|
+
tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- Edit
|
|
8
|
+
- Write
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- AskUserQuestion
|
|
12
|
+
model: haiku
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Configuration Agent: CI/CD Workflow
|
|
16
|
+
|
|
17
|
+
Configure automated CI/CD workflow for testing, linting, and quality checks.
|
|
18
|
+
|
|
19
|
+
## Prompt
|
|
20
|
+
|
|
21
|
+
ROLE: CI/CD Configurator
|
|
22
|
+
|
|
23
|
+
OBJECTIVE
|
|
24
|
+
Set up continuous integration and deployment workflows to automate testing, linting, type checking, and build verification on every commit/PR.
|
|
25
|
+
|
|
26
|
+
## Why CI/CD Matters
|
|
27
|
+
|
|
28
|
+
**IMPORTANT**: Automated CI/CD workflows ensure code quality by:
|
|
29
|
+
- Running tests automatically on every commit
|
|
30
|
+
- Catching bugs before they reach production
|
|
31
|
+
- Enforcing code quality standards (linting, type checking)
|
|
32
|
+
- Validating builds before deployment
|
|
33
|
+
- Providing fast feedback to developers
|
|
34
|
+
|
|
35
|
+
## Configuration Steps
|
|
36
|
+
|
|
37
|
+
### Step 1: Detection Phase
|
|
38
|
+
|
|
39
|
+
Check if CI is already configured:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
echo "📊 Detecting CI Configuration..."
|
|
43
|
+
|
|
44
|
+
# Check for GitHub Actions
|
|
45
|
+
if [ -d .github/workflows ]; then
|
|
46
|
+
WORKFLOW_COUNT=$(ls -1 .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null | wc -l)
|
|
47
|
+
if [ "$WORKFLOW_COUNT" -gt 0 ]; then
|
|
48
|
+
echo "✅ GitHub Actions workflows found: $WORKFLOW_COUNT"
|
|
49
|
+
ls .github/workflows/
|
|
50
|
+
GITHUB_ACTIONS_EXISTS=true
|
|
51
|
+
else
|
|
52
|
+
echo "⚠️ .github/workflows/ exists but no workflows found"
|
|
53
|
+
GITHUB_ACTIONS_EXISTS=false
|
|
54
|
+
fi
|
|
55
|
+
else
|
|
56
|
+
echo "❌ No GitHub Actions workflows"
|
|
57
|
+
GITHUB_ACTIONS_EXISTS=false
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Check for GitLab CI
|
|
61
|
+
if [ -f .gitlab-ci.yml ]; then
|
|
62
|
+
echo "✅ GitLab CI configured (.gitlab-ci.yml exists)"
|
|
63
|
+
GITLAB_CI_EXISTS=true
|
|
64
|
+
else
|
|
65
|
+
echo "❌ No GitLab CI configuration"
|
|
66
|
+
GITLAB_CI_EXISTS=false
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Check for CircleCI
|
|
70
|
+
if [ -f .circleci/config.yml ]; then
|
|
71
|
+
echo "✅ CircleCI configured (.circleci/config.yml exists)"
|
|
72
|
+
CIRCLECI_EXISTS=true
|
|
73
|
+
else
|
|
74
|
+
echo "❌ No CircleCI configuration"
|
|
75
|
+
CIRCLECI_EXISTS=false
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Determine current CI provider
|
|
79
|
+
if [ "$GITHUB_ACTIONS_EXISTS" = true ]; then
|
|
80
|
+
echo "Current CI provider: GitHub Actions"
|
|
81
|
+
CURRENT_PROVIDER="GitHub Actions"
|
|
82
|
+
elif [ "$GITLAB_CI_EXISTS" = true ]; then
|
|
83
|
+
echo "Current CI provider: GitLab CI"
|
|
84
|
+
CURRENT_PROVIDER="GitLab CI"
|
|
85
|
+
elif [ "$CIRCLECI_EXISTS" = true ]; then
|
|
86
|
+
echo "Current CI provider: CircleCI"
|
|
87
|
+
CURRENT_PROVIDER="CircleCI"
|
|
88
|
+
else
|
|
89
|
+
echo "Current CI provider: None"
|
|
90
|
+
CURRENT_PROVIDER="None"
|
|
91
|
+
fi
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Step 2: Ask User for CI Provider
|
|
95
|
+
|
|
96
|
+
Use AskUserQuestion to ask which CI provider to configure:
|
|
97
|
+
|
|
98
|
+
```xml
|
|
99
|
+
<invoke name="AskUserQuestion">
|
|
100
|
+
<parameter name="questions">[{
|
|
101
|
+
"question": "Which CI/CD provider would you like to configure?",
|
|
102
|
+
"header": "CI Provider",
|
|
103
|
+
"multiSelect": false,
|
|
104
|
+
"options": [
|
|
105
|
+
{
|
|
106
|
+
"label": "GitHub Actions (Recommended)",
|
|
107
|
+
"description": "Best for GitHub repos - integrated workflows, free for public repos, 2000 min/month for private"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"label": "GitLab CI",
|
|
111
|
+
"description": "Best for GitLab repos - unlimited minutes on gitlab.com, powerful pipeline features"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"label": "CircleCI",
|
|
115
|
+
"description": "Universal CI platform - works with any Git provider, 30k credits/month free tier"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"label": "Skip CI setup",
|
|
119
|
+
"description": "Don't configure CI now - you can run /AgileFlow:configure again later"
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}]</parameter>
|
|
123
|
+
</invoke>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**If user selects "Skip CI setup"**: Exit gracefully with message:
|
|
127
|
+
```
|
|
128
|
+
⏭️ Skipping CI/CD setup
|
|
129
|
+
You can configure CI later by running /AgileFlow:configure again
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Step 3: Detect Project Commands
|
|
133
|
+
|
|
134
|
+
Try to detect project's test/build/lint commands:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
echo "📦 Detecting project commands..."
|
|
138
|
+
|
|
139
|
+
# Check package.json for Node.js projects
|
|
140
|
+
if [ -f package.json ]; then
|
|
141
|
+
echo "✅ Node.js project detected (package.json found)"
|
|
142
|
+
|
|
143
|
+
# Extract available scripts
|
|
144
|
+
if command -v jq >/dev/null 2>&1; then
|
|
145
|
+
SCRIPTS=$(jq -r '.scripts | keys[]' package.json 2>/dev/null | tr '\n' ', ' | sed 's/,$//')
|
|
146
|
+
echo "Available npm scripts: $SCRIPTS"
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Check for common commands
|
|
150
|
+
grep -q '"test"' package.json && echo " - npm test (detected)"
|
|
151
|
+
grep -q '"lint"' package.json && echo " - npm run lint (detected)"
|
|
152
|
+
grep -q '"build"' package.json && echo " - npm run build (detected)"
|
|
153
|
+
grep -q '"type-check"' package.json && echo " - npm run type-check (detected)"
|
|
154
|
+
|
|
155
|
+
PROJECT_TYPE="nodejs"
|
|
156
|
+
elif [ -f pyproject.toml ] || [ -f setup.py ] || [ -f requirements.txt ]; then
|
|
157
|
+
echo "✅ Python project detected"
|
|
158
|
+
PROJECT_TYPE="python"
|
|
159
|
+
elif [ -f Cargo.toml ]; then
|
|
160
|
+
echo "✅ Rust project detected"
|
|
161
|
+
PROJECT_TYPE="rust"
|
|
162
|
+
elif [ -f go.mod ]; then
|
|
163
|
+
echo "✅ Go project detected"
|
|
164
|
+
PROJECT_TYPE="go"
|
|
165
|
+
else
|
|
166
|
+
echo "⚠️ Could not detect project type"
|
|
167
|
+
PROJECT_TYPE="unknown"
|
|
168
|
+
fi
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Step 4: Ask User Which Commands to Run
|
|
172
|
+
|
|
173
|
+
Use AskUserQuestion with multiple selection:
|
|
174
|
+
|
|
175
|
+
```xml
|
|
176
|
+
<invoke name="AskUserQuestion">
|
|
177
|
+
<parameter name="questions">[{
|
|
178
|
+
"question": "Which commands should run in CI? (Select multiple)",
|
|
179
|
+
"header": "CI Commands",
|
|
180
|
+
"multiSelect": true,
|
|
181
|
+
"options": [
|
|
182
|
+
{
|
|
183
|
+
"label": "Install dependencies",
|
|
184
|
+
"description": "Install project dependencies before running other commands (recommended)"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"label": "Run tests",
|
|
188
|
+
"description": "Execute test suite to verify code correctness"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"label": "Run linter",
|
|
192
|
+
"description": "Check code style and enforce coding standards"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"label": "Run type checker",
|
|
196
|
+
"description": "Verify TypeScript types or other static type checking"
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
}]</parameter>
|
|
200
|
+
</invoke>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Note**: User can select multiple options. Build is intentionally separate (asked next) since most projects need it.
|
|
204
|
+
|
|
205
|
+
### Step 5: Ask for Specific Command Strings
|
|
206
|
+
|
|
207
|
+
**IMPORTANT**: Batch related questions together (max 4 per call). Provide smart defaults as options, user can select "Other" for custom commands.
|
|
208
|
+
|
|
209
|
+
**For Node.js projects**, ask all at once:
|
|
210
|
+
|
|
211
|
+
```xml
|
|
212
|
+
<invoke name="AskUserQuestion">
|
|
213
|
+
<parameter name="questions">[
|
|
214
|
+
{
|
|
215
|
+
"question": "What command runs your tests?",
|
|
216
|
+
"header": "Test cmd",
|
|
217
|
+
"multiSelect": false,
|
|
218
|
+
"options": [
|
|
219
|
+
{"label": "npm test (Recommended)", "description": "Standard npm test script"},
|
|
220
|
+
{"label": "npm run test:unit", "description": "Separate unit test script"},
|
|
221
|
+
{"label": "jest", "description": "Run Jest directly"},
|
|
222
|
+
{"label": "vitest", "description": "Run Vitest directly"}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"question": "What command runs your linter?",
|
|
227
|
+
"header": "Lint cmd",
|
|
228
|
+
"multiSelect": false,
|
|
229
|
+
"options": [
|
|
230
|
+
{"label": "npm run lint (Recommended)", "description": "Standard lint script"},
|
|
231
|
+
{"label": "eslint .", "description": "Run ESLint directly on all files"},
|
|
232
|
+
{"label": "npm run lint:fix", "description": "Lint with auto-fix"},
|
|
233
|
+
{"label": "biome check", "description": "Use Biome linter"}
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"question": "What command runs type checking?",
|
|
238
|
+
"header": "Type cmd",
|
|
239
|
+
"multiSelect": false,
|
|
240
|
+
"options": [
|
|
241
|
+
{"label": "npm run type-check (Recommended)", "description": "Standard type-check script"},
|
|
242
|
+
{"label": "tsc --noEmit", "description": "TypeScript compiler check without output"},
|
|
243
|
+
{"label": "tsc", "description": "Full TypeScript compilation"},
|
|
244
|
+
{"label": "skip", "description": "Skip type checking"}
|
|
245
|
+
]
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"question": "What command builds your project?",
|
|
249
|
+
"header": "Build cmd",
|
|
250
|
+
"multiSelect": false,
|
|
251
|
+
"options": [
|
|
252
|
+
{"label": "npm run build (Recommended)", "description": "Standard build script"},
|
|
253
|
+
{"label": "vite build", "description": "Vite bundler"},
|
|
254
|
+
{"label": "next build", "description": "Next.js build"},
|
|
255
|
+
{"label": "tsc", "description": "TypeScript compiler"}
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
]</parameter>
|
|
259
|
+
</invoke>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**For Python projects**:
|
|
263
|
+
|
|
264
|
+
```xml
|
|
265
|
+
<invoke name="AskUserQuestion">
|
|
266
|
+
<parameter name="questions">[
|
|
267
|
+
{
|
|
268
|
+
"question": "What command runs your tests?",
|
|
269
|
+
"header": "Test cmd",
|
|
270
|
+
"multiSelect": false,
|
|
271
|
+
"options": [
|
|
272
|
+
{"label": "pytest (Recommended)", "description": "Popular Python testing framework"},
|
|
273
|
+
{"label": "python -m pytest", "description": "Run pytest as module"},
|
|
274
|
+
{"label": "python -m unittest", "description": "Built-in unittest framework"},
|
|
275
|
+
{"label": "nose2", "description": "Nose2 testing framework"}
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"question": "What command runs your linter?",
|
|
280
|
+
"header": "Lint cmd",
|
|
281
|
+
"multiSelect": false,
|
|
282
|
+
"options": [
|
|
283
|
+
{"label": "flake8 (Recommended)", "description": "Style guide enforcement"},
|
|
284
|
+
{"label": "pylint", "description": "Comprehensive code analysis"},
|
|
285
|
+
{"label": "ruff", "description": "Fast Python linter"},
|
|
286
|
+
{"label": "black --check", "description": "Check Black formatting"}
|
|
287
|
+
]
|
|
288
|
+
}
|
|
289
|
+
]</parameter>
|
|
290
|
+
</invoke>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**For other project types**, adjust options accordingly. User always has "Other" option to enter custom commands.
|
|
294
|
+
|
|
295
|
+
**After receiving answers**: Parse the responses and use "Other" value if user provided custom command.
|
|
296
|
+
|
|
297
|
+
### Step 6: Create CI Workflow File
|
|
298
|
+
|
|
299
|
+
Based on provider selection, create appropriate workflow file.
|
|
300
|
+
|
|
301
|
+
#### GitHub Actions Workflow
|
|
302
|
+
|
|
303
|
+
Create `.github/workflows/ci.yml`:
|
|
304
|
+
|
|
305
|
+
```yaml
|
|
306
|
+
name: CI
|
|
307
|
+
|
|
308
|
+
on:
|
|
309
|
+
push:
|
|
310
|
+
branches: [ main, develop ]
|
|
311
|
+
pull_request:
|
|
312
|
+
branches: [ main, develop ]
|
|
313
|
+
|
|
314
|
+
jobs:
|
|
315
|
+
test:
|
|
316
|
+
runs-on: ubuntu-latest
|
|
317
|
+
|
|
318
|
+
steps:
|
|
319
|
+
- uses: actions/checkout@v4
|
|
320
|
+
|
|
321
|
+
- name: Setup Node.js
|
|
322
|
+
uses: actions/setup-node@v4
|
|
323
|
+
with:
|
|
324
|
+
node-version: '20'
|
|
325
|
+
cache: 'npm'
|
|
326
|
+
|
|
327
|
+
{{#if installDeps}}
|
|
328
|
+
- name: Install dependencies
|
|
329
|
+
run: npm ci
|
|
330
|
+
{{/if}}
|
|
331
|
+
|
|
332
|
+
{{#if runTests}}
|
|
333
|
+
- name: Run tests
|
|
334
|
+
run: {{testCommand}}
|
|
335
|
+
{{/if}}
|
|
336
|
+
|
|
337
|
+
{{#if runLint}}
|
|
338
|
+
- name: Run linter
|
|
339
|
+
run: {{lintCommand}}
|
|
340
|
+
{{/if}}
|
|
341
|
+
|
|
342
|
+
{{#if runTypeCheck}}
|
|
343
|
+
- name: Type check
|
|
344
|
+
run: {{typeCheckCommand}}
|
|
345
|
+
{{/if}}
|
|
346
|
+
|
|
347
|
+
{{#if runBuild}}
|
|
348
|
+
- name: Build
|
|
349
|
+
run: {{buildCommand}}
|
|
350
|
+
{{/if}}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Note**: Replace `{{variables}}` with actual values from user responses.
|
|
354
|
+
|
|
355
|
+
#### GitLab CI Configuration
|
|
356
|
+
|
|
357
|
+
Create `.gitlab-ci.yml`:
|
|
358
|
+
|
|
359
|
+
```yaml
|
|
360
|
+
stages:
|
|
361
|
+
- test
|
|
362
|
+
- build
|
|
363
|
+
|
|
364
|
+
variables:
|
|
365
|
+
NODE_VERSION: "20"
|
|
366
|
+
|
|
367
|
+
before_script:
|
|
368
|
+
- node --version
|
|
369
|
+
- npm --version
|
|
370
|
+
|
|
371
|
+
{{#if installDeps}}
|
|
372
|
+
install:
|
|
373
|
+
stage: .pre
|
|
374
|
+
script:
|
|
375
|
+
- npm ci
|
|
376
|
+
cache:
|
|
377
|
+
paths:
|
|
378
|
+
- node_modules/
|
|
379
|
+
{{/if}}
|
|
380
|
+
|
|
381
|
+
{{#if runTests}}
|
|
382
|
+
test:
|
|
383
|
+
stage: test
|
|
384
|
+
script:
|
|
385
|
+
- {{testCommand}}
|
|
386
|
+
{{/if}}
|
|
387
|
+
|
|
388
|
+
{{#if runLint}}
|
|
389
|
+
lint:
|
|
390
|
+
stage: test
|
|
391
|
+
script:
|
|
392
|
+
- {{lintCommand}}
|
|
393
|
+
{{/if}}
|
|
394
|
+
|
|
395
|
+
{{#if runTypeCheck}}
|
|
396
|
+
type-check:
|
|
397
|
+
stage: test
|
|
398
|
+
script:
|
|
399
|
+
- {{typeCheckCommand}}
|
|
400
|
+
{{/if}}
|
|
401
|
+
|
|
402
|
+
{{#if runBuild}}
|
|
403
|
+
build:
|
|
404
|
+
stage: build
|
|
405
|
+
script:
|
|
406
|
+
- {{buildCommand}}
|
|
407
|
+
{{/if}}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### CircleCI Configuration
|
|
411
|
+
|
|
412
|
+
Create `.circleci/config.yml`:
|
|
413
|
+
|
|
414
|
+
```yaml
|
|
415
|
+
version: 2.1
|
|
416
|
+
|
|
417
|
+
orbs:
|
|
418
|
+
node: circleci/node@5.1.0
|
|
419
|
+
|
|
420
|
+
jobs:
|
|
421
|
+
test-and-build:
|
|
422
|
+
docker:
|
|
423
|
+
- image: cimg/node:20.0
|
|
424
|
+
steps:
|
|
425
|
+
- checkout
|
|
426
|
+
|
|
427
|
+
{{#if installDeps}}
|
|
428
|
+
- node/install-packages:
|
|
429
|
+
pkg-manager: npm
|
|
430
|
+
{{/if}}
|
|
431
|
+
|
|
432
|
+
{{#if runTests}}
|
|
433
|
+
- run:
|
|
434
|
+
name: Run tests
|
|
435
|
+
command: {{testCommand}}
|
|
436
|
+
{{/if}}
|
|
437
|
+
|
|
438
|
+
{{#if runLint}}
|
|
439
|
+
- run:
|
|
440
|
+
name: Run linter
|
|
441
|
+
command: {{lintCommand}}
|
|
442
|
+
{{/if}}
|
|
443
|
+
|
|
444
|
+
{{#if runTypeCheck}}
|
|
445
|
+
- run:
|
|
446
|
+
name: Type check
|
|
447
|
+
command: {{typeCheckCommand}}
|
|
448
|
+
{{/if}}
|
|
449
|
+
|
|
450
|
+
{{#if runBuild}}
|
|
451
|
+
- run:
|
|
452
|
+
name: Build
|
|
453
|
+
command: {{buildCommand}}
|
|
454
|
+
{{/if}}
|
|
455
|
+
|
|
456
|
+
workflows:
|
|
457
|
+
test-workflow:
|
|
458
|
+
jobs:
|
|
459
|
+
- test-and-build
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Step 7: Create Workflow File with Bash
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# Example for GitHub Actions
|
|
466
|
+
mkdir -p .github/workflows
|
|
467
|
+
|
|
468
|
+
cat > .github/workflows/ci.yml << 'EOF'
|
|
469
|
+
name: CI
|
|
470
|
+
|
|
471
|
+
on:
|
|
472
|
+
push:
|
|
473
|
+
branches: [ main, develop ]
|
|
474
|
+
pull_request:
|
|
475
|
+
branches: [ main, develop ]
|
|
476
|
+
|
|
477
|
+
jobs:
|
|
478
|
+
test:
|
|
479
|
+
runs-on: ubuntu-latest
|
|
480
|
+
|
|
481
|
+
steps:
|
|
482
|
+
- uses: actions/checkout@v4
|
|
483
|
+
|
|
484
|
+
- name: Setup Node.js
|
|
485
|
+
uses: actions/setup-node@v4
|
|
486
|
+
with:
|
|
487
|
+
node-version: '20'
|
|
488
|
+
cache: 'npm'
|
|
489
|
+
|
|
490
|
+
- name: Install dependencies
|
|
491
|
+
run: npm ci
|
|
492
|
+
|
|
493
|
+
- name: Run tests
|
|
494
|
+
run: npm test
|
|
495
|
+
|
|
496
|
+
- name: Run linter
|
|
497
|
+
run: npm run lint
|
|
498
|
+
|
|
499
|
+
- name: Build
|
|
500
|
+
run: npm run build
|
|
501
|
+
EOF
|
|
502
|
+
|
|
503
|
+
echo "✅ Created .github/workflows/ci.yml"
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
**Important**: Dynamically build the YAML based on user's selections. Don't include steps for commands they didn't select.
|
|
507
|
+
|
|
508
|
+
### Step 8: Update CLAUDE.md
|
|
509
|
+
|
|
510
|
+
Add CI/CD documentation to project's CLAUDE.md:
|
|
511
|
+
|
|
512
|
+
```markdown
|
|
513
|
+
## CI/CD (Continuous Integration)
|
|
514
|
+
|
|
515
|
+
This project uses {{PROVIDER}} for automated testing and quality checks.
|
|
516
|
+
|
|
517
|
+
### Workflow Configuration
|
|
518
|
+
|
|
519
|
+
**Location**: {{WORKFLOW_FILE_PATH}}
|
|
520
|
+
|
|
521
|
+
**Triggers**:
|
|
522
|
+
- Push to main/develop branches
|
|
523
|
+
- Pull requests to main/develop
|
|
524
|
+
|
|
525
|
+
**Jobs**:
|
|
526
|
+
{{#if runTests}}
|
|
527
|
+
- **Tests**: Runs `{{testCommand}}`
|
|
528
|
+
{{/if}}
|
|
529
|
+
{{#if runLint}}
|
|
530
|
+
- **Linting**: Runs `{{lintCommand}}`
|
|
531
|
+
{{/if}}
|
|
532
|
+
{{#if runTypeCheck}}
|
|
533
|
+
- **Type Checking**: Runs `{{typeCheckCommand}}`
|
|
534
|
+
{{/if}}
|
|
535
|
+
{{#if runBuild}}
|
|
536
|
+
- **Build**: Runs `{{buildCommand}}`
|
|
537
|
+
{{/if}}
|
|
538
|
+
|
|
539
|
+
### Running CI Locally
|
|
540
|
+
|
|
541
|
+
Before pushing, you can run the same checks locally:
|
|
542
|
+
|
|
543
|
+
\`\`\`bash
|
|
544
|
+
{{#if installDeps}}
|
|
545
|
+
# Install dependencies
|
|
546
|
+
npm ci
|
|
547
|
+
{{/if}}
|
|
548
|
+
|
|
549
|
+
{{#if runTests}}
|
|
550
|
+
# Run tests
|
|
551
|
+
{{testCommand}}
|
|
552
|
+
{{/if}}
|
|
553
|
+
|
|
554
|
+
{{#if runLint}}
|
|
555
|
+
# Run linter
|
|
556
|
+
{{lintCommand}}
|
|
557
|
+
{{/if}}
|
|
558
|
+
|
|
559
|
+
{{#if runTypeCheck}}
|
|
560
|
+
# Type check
|
|
561
|
+
{{typeCheckCommand}}
|
|
562
|
+
{{/if}}
|
|
563
|
+
|
|
564
|
+
{{#if runBuild}}
|
|
565
|
+
# Build
|
|
566
|
+
{{buildCommand}}
|
|
567
|
+
{{/if}}
|
|
568
|
+
\`\`\`
|
|
569
|
+
|
|
570
|
+
### CI Status
|
|
571
|
+
|
|
572
|
+
Check CI status:
|
|
573
|
+
- {{PROVIDER_LINK}} ({{PROVIDER_URL}})
|
|
574
|
+
- Status badge: 
|
|
575
|
+
|
|
576
|
+
### Troubleshooting
|
|
577
|
+
|
|
578
|
+
If CI fails:
|
|
579
|
+
1. Check the logs in {{PROVIDER}} dashboard
|
|
580
|
+
2. Run the failing command locally
|
|
581
|
+
3. Fix the issue and push again
|
|
582
|
+
4. CI will re-run automatically
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
**Note**: Replace `{{variables}}` with actual values.
|
|
586
|
+
|
|
587
|
+
### Step 9: Verify Configuration (Optional)
|
|
588
|
+
|
|
589
|
+
**IMPORTANT**: Always ask user permission before running verification.
|
|
590
|
+
|
|
591
|
+
**Ask if user wants to verify**:
|
|
592
|
+
|
|
593
|
+
```xml
|
|
594
|
+
<invoke name="AskUserQuestion">
|
|
595
|
+
<parameter name="questions">[{
|
|
596
|
+
"question": "Verify CI configuration? (Tests YAML syntax and runs commands locally)",
|
|
597
|
+
"header": "Verify CI",
|
|
598
|
+
"multiSelect": false,
|
|
599
|
+
"options": [
|
|
600
|
+
{
|
|
601
|
+
"label": "Yes, verify now",
|
|
602
|
+
"description": "Run YAML validation and test commands locally to catch issues early"
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
"label": "No, skip verification",
|
|
606
|
+
"description": "Skip verification - you can test manually or let CI run on first push"
|
|
607
|
+
}
|
|
608
|
+
]
|
|
609
|
+
}]</parameter>
|
|
610
|
+
</invoke>
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
**If user selects "No, skip verification"**: Skip to success output.
|
|
614
|
+
|
|
615
|
+
**If user chooses to verify**, run these checks:
|
|
616
|
+
|
|
617
|
+
#### 9.1: Validate YAML Syntax
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
echo "🔍 Step 1: Validating YAML syntax..."
|
|
621
|
+
|
|
622
|
+
WORKFLOW_FILE=".github/workflows/ci.yml" # Or .gitlab-ci.yml, etc.
|
|
623
|
+
|
|
624
|
+
# Check with Python (most reliable)
|
|
625
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
626
|
+
python3 << EOF
|
|
627
|
+
import yaml
|
|
628
|
+
import sys
|
|
629
|
+
|
|
630
|
+
try:
|
|
631
|
+
with open('$WORKFLOW_FILE', 'r') as f:
|
|
632
|
+
yaml.safe_load(f)
|
|
633
|
+
print("✅ YAML syntax is valid")
|
|
634
|
+
sys.exit(0)
|
|
635
|
+
except yaml.YAMLError as e:
|
|
636
|
+
print(f"❌ YAML syntax error: {e}")
|
|
637
|
+
sys.exit(1)
|
|
638
|
+
except FileNotFoundError:
|
|
639
|
+
print(f"❌ File not found: $WORKFLOW_FILE")
|
|
640
|
+
sys.exit(1)
|
|
641
|
+
EOF
|
|
642
|
+
|
|
643
|
+
if [ $? -eq 0 ]; then
|
|
644
|
+
YAML_VALID=true
|
|
645
|
+
else
|
|
646
|
+
YAML_VALID=false
|
|
647
|
+
fi
|
|
648
|
+
else
|
|
649
|
+
echo "⚠️ Cannot validate YAML (python3 not found)"
|
|
650
|
+
echo " Please check syntax manually at: https://www.yamllint.com/"
|
|
651
|
+
YAML_VALID="unknown"
|
|
652
|
+
fi
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
#### 9.2: Test Commands Locally
|
|
656
|
+
|
|
657
|
+
**Ask permission to run tests**:
|
|
658
|
+
|
|
659
|
+
```xml
|
|
660
|
+
<invoke name="AskUserQuestion">
|
|
661
|
+
<parameter name="questions">[{
|
|
662
|
+
"question": "Run CI commands locally to test them? (This will execute: install, test, lint, build)",
|
|
663
|
+
"header": "Test local",
|
|
664
|
+
"multiSelect": false,
|
|
665
|
+
"options": [
|
|
666
|
+
{
|
|
667
|
+
"label": "Yes, run tests now",
|
|
668
|
+
"description": "Execute all CI commands locally to verify they work before pushing"
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
"label": "No, skip local testing",
|
|
672
|
+
"description": "Skip local testing - assume commands work or test manually"
|
|
673
|
+
}
|
|
674
|
+
]
|
|
675
|
+
}]</parameter>
|
|
676
|
+
</invoke>
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
**If user agrees, run commands**:
|
|
680
|
+
|
|
681
|
+
```bash
|
|
682
|
+
if [ "$runLocal" = "Yes, run tests now" ]; then
|
|
683
|
+
echo ""
|
|
684
|
+
echo "🧪 Step 2: Testing CI commands locally..."
|
|
685
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
686
|
+
|
|
687
|
+
FAILED_COMMANDS=0
|
|
688
|
+
PASSED_COMMANDS=0
|
|
689
|
+
|
|
690
|
+
# Test each command that was configured
|
|
691
|
+
{{#if installDeps}}
|
|
692
|
+
echo ""
|
|
693
|
+
echo "Running: npm ci"
|
|
694
|
+
if npm ci; then
|
|
695
|
+
echo "✅ PASSED: npm ci"
|
|
696
|
+
PASSED_COMMANDS=$((PASSED_COMMANDS + 1))
|
|
697
|
+
else
|
|
698
|
+
echo "❌ FAILED: npm ci (exit code: $?)"
|
|
699
|
+
FAILED_COMMANDS=$((FAILED_COMMANDS + 1))
|
|
700
|
+
fi
|
|
701
|
+
{{/if}}
|
|
702
|
+
|
|
703
|
+
{{#if runTests}}
|
|
704
|
+
echo ""
|
|
705
|
+
echo "Running: {{testCommand}}"
|
|
706
|
+
if {{testCommand}}; then
|
|
707
|
+
echo "✅ PASSED: {{testCommand}}"
|
|
708
|
+
PASSED_COMMANDS=$((PASSED_COMMANDS + 1))
|
|
709
|
+
else
|
|
710
|
+
echo "❌ FAILED: {{testCommand}} (exit code: $?)"
|
|
711
|
+
FAILED_COMMANDS=$((FAILED_COMMANDS + 1))
|
|
712
|
+
fi
|
|
713
|
+
{{/if}}
|
|
714
|
+
|
|
715
|
+
{{#if runLint}}
|
|
716
|
+
echo ""
|
|
717
|
+
echo "Running: {{lintCommand}}"
|
|
718
|
+
if {{lintCommand}}; then
|
|
719
|
+
echo "✅ PASSED: {{lintCommand}}"
|
|
720
|
+
PASSED_COMMANDS=$((PASSED_COMMANDS + 1))
|
|
721
|
+
else
|
|
722
|
+
echo "❌ FAILED: {{lintCommand}} (exit code: $?)"
|
|
723
|
+
FAILED_COMMANDS=$((FAILED_COMMANDS + 1))
|
|
724
|
+
fi
|
|
725
|
+
{{/if}}
|
|
726
|
+
|
|
727
|
+
{{#if runTypeCheck}}
|
|
728
|
+
echo ""
|
|
729
|
+
echo "Running: {{typeCheckCommand}}"
|
|
730
|
+
if {{typeCheckCommand}}; then
|
|
731
|
+
echo "✅ PASSED: {{typeCheckCommand}}"
|
|
732
|
+
PASSED_COMMANDS=$((PASSED_COMMANDS + 1))
|
|
733
|
+
else
|
|
734
|
+
echo "❌ FAILED: {{typeCheckCommand}} (exit code: $?)"
|
|
735
|
+
FAILED_COMMANDS=$((FAILED_COMMANDS + 1))
|
|
736
|
+
fi
|
|
737
|
+
{{/if}}
|
|
738
|
+
|
|
739
|
+
{{#if runBuild}}
|
|
740
|
+
echo ""
|
|
741
|
+
echo "Running: {{buildCommand}}"
|
|
742
|
+
if {{buildCommand}}; then
|
|
743
|
+
echo "✅ PASSED: {{buildCommand}}"
|
|
744
|
+
PASSED_COMMANDS=$((PASSED_COMMANDS + 1))
|
|
745
|
+
else
|
|
746
|
+
echo "❌ FAILED: {{buildCommand}} (exit code: $?)"
|
|
747
|
+
FAILED_COMMANDS=$((FAILED_COMMANDS + 1))
|
|
748
|
+
fi
|
|
749
|
+
{{/if}}
|
|
750
|
+
|
|
751
|
+
echo ""
|
|
752
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
753
|
+
echo "Results: $PASSED_COMMANDS passed, $FAILED_COMMANDS failed"
|
|
754
|
+
|
|
755
|
+
if [ $FAILED_COMMANDS -eq 0 ]; then
|
|
756
|
+
echo "✅ All CI commands passed locally"
|
|
757
|
+
LOCAL_TEST_RESULT="PASSED"
|
|
758
|
+
else
|
|
759
|
+
echo "❌ Some CI commands failed"
|
|
760
|
+
echo ""
|
|
761
|
+
echo "⚠️ WARNING: CI will fail when you push!"
|
|
762
|
+
echo " Fix the failing commands before pushing to remote"
|
|
763
|
+
LOCAL_TEST_RESULT="FAILED"
|
|
764
|
+
fi
|
|
765
|
+
fi
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
#### 9.3: Trigger Remote CI Run (Optional)
|
|
769
|
+
|
|
770
|
+
**Only for GitHub Actions** (requires token):
|
|
771
|
+
|
|
772
|
+
**Check if user wants to trigger remote CI**:
|
|
773
|
+
|
|
774
|
+
```xml
|
|
775
|
+
<invoke name="AskUserQuestion">
|
|
776
|
+
<parameter name="questions">[{
|
|
777
|
+
"question": "Trigger a test CI run on GitHub? (Requires GitHub token with 'workflow' scope)",
|
|
778
|
+
"header": "Trigger CI",
|
|
779
|
+
"multiSelect": false,
|
|
780
|
+
"options": [
|
|
781
|
+
{
|
|
782
|
+
"label": "Yes, trigger remote CI",
|
|
783
|
+
"description": "Use GitHub API to trigger a workflow run now (requires token)"
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
"label": "No, I'll push manually",
|
|
787
|
+
"description": "Skip remote trigger - CI will run when you push code"
|
|
788
|
+
}
|
|
789
|
+
]
|
|
790
|
+
}]</parameter>
|
|
791
|
+
</invoke>
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
**If yes, check for token**:
|
|
795
|
+
|
|
796
|
+
```bash
|
|
797
|
+
if [ "$triggerRemote" = "Yes, trigger remote CI" ]; then
|
|
798
|
+
echo ""
|
|
799
|
+
echo "🚀 Step 3: Triggering remote CI run..."
|
|
800
|
+
|
|
801
|
+
# Check for token in .claude/settings.local.json
|
|
802
|
+
if [ -f .claude/settings.local.json ]; then
|
|
803
|
+
GITHUB_TOKEN=$(jq -r '.env.GITHUB_TOKEN // ""' .claude/settings.local.json 2>/dev/null)
|
|
804
|
+
fi
|
|
805
|
+
|
|
806
|
+
if [ -z "$GITHUB_TOKEN" ] || [ "$GITHUB_TOKEN" = "null" ]; then
|
|
807
|
+
echo "⚠️ GitHub token not found in .claude/settings.local.json"
|
|
808
|
+
fi
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
**Ask user for token** (2 questions - token + save preference):
|
|
812
|
+
|
|
813
|
+
```xml
|
|
814
|
+
<invoke name="AskUserQuestion">
|
|
815
|
+
<parameter name="questions">[
|
|
816
|
+
{
|
|
817
|
+
"question": "GitHub token not found. Enter your personal access token? (Create at: github.com/settings/tokens/new, Required scopes: repo, workflow)",
|
|
818
|
+
"header": "Token",
|
|
819
|
+
"multiSelect": false,
|
|
820
|
+
"options": [
|
|
821
|
+
{
|
|
822
|
+
"label": "Skip - I'll push manually",
|
|
823
|
+
"description": "Skip triggering CI remotely - just push code and CI runs automatically"
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"label": "Other",
|
|
827
|
+
"description": "Enter token (select this, then type your ghp_xxx token in the text field)"
|
|
828
|
+
}
|
|
829
|
+
]
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
"question": "Save token to .claude/settings.local.json for future use? (File is gitignored and secure)",
|
|
833
|
+
"header": "Save token",
|
|
834
|
+
"multiSelect": false,
|
|
835
|
+
"options": [
|
|
836
|
+
{
|
|
837
|
+
"label": "Yes, save token",
|
|
838
|
+
"description": "Store securely in .claude/settings.local.json (gitignored, chmod 600)"
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
"label": "No, use once only",
|
|
842
|
+
"description": "Use token just this time - you'll be asked again later"
|
|
843
|
+
}
|
|
844
|
+
]
|
|
845
|
+
}
|
|
846
|
+
]</parameter>
|
|
847
|
+
</invoke>
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
**Note**: User selects "Other" for the first question and enters token in the text field.
|
|
851
|
+
|
|
852
|
+
**Save token if user agrees**:
|
|
853
|
+
|
|
854
|
+
```bash
|
|
855
|
+
if [ "$saveToken" = "Yes, save token" ]; then
|
|
856
|
+
# Create .claude/settings.local.json if doesn't exist
|
|
857
|
+
if [ ! -f .claude/settings.local.json ]; then
|
|
858
|
+
echo '{"env":{}}' > .claude/settings.local.json
|
|
859
|
+
chmod 600 .claude/settings.local.json
|
|
860
|
+
fi
|
|
861
|
+
|
|
862
|
+
# Add token
|
|
863
|
+
jq ".env.GITHUB_TOKEN = \"$token\"" .claude/settings.local.json > .claude/settings.local.json.tmp && mv .claude/settings.local.json.tmp .claude/settings.local.json
|
|
864
|
+
|
|
865
|
+
echo "✅ Token saved to .claude/settings.local.json (chmod 600)"
|
|
866
|
+
GITHUB_TOKEN="$token"
|
|
867
|
+
fi
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
**Trigger workflow via GitHub API**:
|
|
871
|
+
|
|
872
|
+
```bash
|
|
873
|
+
# Extract repo owner and name from git remote
|
|
874
|
+
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
|
|
875
|
+
if [[ "$REMOTE_URL" =~ github.com[:/]([^/]+)/([^/.]+) ]]; then
|
|
876
|
+
REPO_OWNER="${BASH_REMATCH[1]}"
|
|
877
|
+
REPO_NAME="${BASH_REMATCH[2]}"
|
|
878
|
+
REPO="$REPO_OWNER/$REPO_NAME"
|
|
879
|
+
else
|
|
880
|
+
echo "❌ Cannot extract repo info from remote URL"
|
|
881
|
+
echo " Remote URL: $REMOTE_URL"
|
|
882
|
+
exit 1
|
|
883
|
+
fi
|
|
884
|
+
|
|
885
|
+
# Trigger workflow
|
|
886
|
+
echo "Triggering workflow for: $REPO"
|
|
887
|
+
|
|
888
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
|
|
889
|
+
-H "Accept: application/vnd.github.v3+json" \
|
|
890
|
+
-H "Authorization: token $GITHUB_TOKEN" \
|
|
891
|
+
"https://api.github.com/repos/${REPO}/actions/workflows/ci.yml/dispatches" \
|
|
892
|
+
-d '{"ref":"main"}')
|
|
893
|
+
|
|
894
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
895
|
+
BODY=$(echo "$RESPONSE" | head -n-1)
|
|
896
|
+
|
|
897
|
+
if [ "$HTTP_CODE" = "204" ]; then
|
|
898
|
+
echo "✅ CI workflow triggered successfully"
|
|
899
|
+
echo " View at: https://github.com/${REPO}/actions"
|
|
900
|
+
REMOTE_TRIGGER_RESULT="SUCCESS"
|
|
901
|
+
else
|
|
902
|
+
echo "❌ Failed to trigger workflow (HTTP $HTTP_CODE)"
|
|
903
|
+
echo " Response: $BODY"
|
|
904
|
+
echo ""
|
|
905
|
+
echo "Possible issues:"
|
|
906
|
+
echo "- Invalid token or insufficient permissions"
|
|
907
|
+
echo "- Workflow file not pushed to remote yet"
|
|
908
|
+
echo "- Wrong branch (trying 'main', repo might use 'master')"
|
|
909
|
+
REMOTE_TRIGGER_RESULT="FAILED"
|
|
910
|
+
fi
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
### Verification Report
|
|
914
|
+
|
|
915
|
+
After verification, print summary:
|
|
916
|
+
|
|
917
|
+
```
|
|
918
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
919
|
+
🔍 VERIFICATION REPORT
|
|
920
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
921
|
+
|
|
922
|
+
Configuration: CI/CD ({{PROVIDER}})
|
|
923
|
+
Workflow file: {{WORKFLOW_FILE_PATH}}
|
|
924
|
+
|
|
925
|
+
Checks performed:
|
|
926
|
+
✅ YAML syntax validation: {{YAML_VALID ? "PASSED" : "FAILED"}}
|
|
927
|
+
{{#if runLocal}}
|
|
928
|
+
{{LOCAL_TEST_RESULT == "PASSED" ? "✅" : "❌"}} Local command tests: {{LOCAL_TEST_RESULT}} ({{PASSED_COMMANDS}}/{{TOTAL_COMMANDS}})
|
|
929
|
+
{{#if runTests}} - {{testCommand}}{{/if}}
|
|
930
|
+
{{#if runLint}} - {{lintCommand}}{{/if}}
|
|
931
|
+
{{#if runTypeCheck}} - {{typeCheckCommand}}{{/if}}
|
|
932
|
+
{{#if runBuild}} - {{buildCommand}}{{/if}}
|
|
933
|
+
{{else}}
|
|
934
|
+
⏭️ Local command tests: SKIPPED (user declined)
|
|
935
|
+
{{/if}}
|
|
936
|
+
{{#if triggerRemote == "Yes"}}
|
|
937
|
+
{{REMOTE_TRIGGER_RESULT == "SUCCESS" ? "✅" : "❌"}} Remote trigger: {{REMOTE_TRIGGER_RESULT}}
|
|
938
|
+
{{else}}
|
|
939
|
+
⏭️ Remote trigger: SKIPPED
|
|
940
|
+
{{/if}}
|
|
941
|
+
|
|
942
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
943
|
+
Overall: {{YAML_VALID && (LOCAL_TEST_RESULT == "PASSED" || !runLocal) ? "✅ VERIFIED" : "⚠️ ISSUES FOUND"}}
|
|
944
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
**If verification failed**:
|
|
948
|
+
|
|
949
|
+
```
|
|
950
|
+
⚠️ Some checks failed. You can still commit the workflow, but it may fail in CI.
|
|
951
|
+
|
|
952
|
+
Recommended actions:
|
|
953
|
+
{{#if !YAML_VALID}}
|
|
954
|
+
- Fix YAML syntax errors before committing
|
|
955
|
+
{{/if}}
|
|
956
|
+
{{#if LOCAL_TEST_RESULT == "FAILED"}}
|
|
957
|
+
- Fix failing commands (see output above)
|
|
958
|
+
- Re-run verification after fixes
|
|
959
|
+
{{/if}}
|
|
960
|
+
|
|
961
|
+
Continue anyway? (The workflow file has been created)
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
## Success Output
|
|
965
|
+
|
|
966
|
+
After successful configuration (with or without verification), print:
|
|
967
|
+
|
|
968
|
+
```
|
|
969
|
+
✅ CI/CD Workflow Configured
|
|
970
|
+
|
|
971
|
+
Provider: {{PROVIDER}}
|
|
972
|
+
Workflow file: {{WORKFLOW_FILE_PATH}}
|
|
973
|
+
|
|
974
|
+
Commands configured:
|
|
975
|
+
{{#if runTests}}
|
|
976
|
+
✅ Tests: {{testCommand}}
|
|
977
|
+
{{/if}}
|
|
978
|
+
{{#if runLint}}
|
|
979
|
+
✅ Linter: {{lintCommand}}
|
|
980
|
+
{{/if}}
|
|
981
|
+
{{#if runTypeCheck}}
|
|
982
|
+
✅ Type checking: {{typeCheckCommand}}
|
|
983
|
+
{{/if}}
|
|
984
|
+
{{#if runBuild}}
|
|
985
|
+
✅ Build: {{buildCommand}}
|
|
986
|
+
{{/if}}
|
|
987
|
+
|
|
988
|
+
Next steps:
|
|
989
|
+
1. Commit the workflow file:
|
|
990
|
+
git add {{WORKFLOW_FILE_PATH}}
|
|
991
|
+
git commit -m "ci: add {{PROVIDER}} workflow"
|
|
992
|
+
|
|
993
|
+
2. Push to trigger CI:
|
|
994
|
+
git push origin main
|
|
995
|
+
|
|
996
|
+
3. Check CI status:
|
|
997
|
+
{{PROVIDER_URL}}
|
|
998
|
+
|
|
999
|
+
4. Add status badge to README.md (optional):
|
|
1000
|
+
{{BADGE_MARKDOWN}}
|
|
1001
|
+
|
|
1002
|
+
Note: CI will run automatically on every push and pull request.
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
## Provider-Specific Details
|
|
1006
|
+
|
|
1007
|
+
### GitHub Actions
|
|
1008
|
+
- File: `.github/workflows/ci.yml`
|
|
1009
|
+
- View results: `https://github.com/{user}/{repo}/actions`
|
|
1010
|
+
- Badge: ``
|
|
1011
|
+
|
|
1012
|
+
### GitLab CI
|
|
1013
|
+
- File: `.gitlab-ci.yml`
|
|
1014
|
+
- View results: `https://gitlab.com/{user}/{repo}/-/pipelines`
|
|
1015
|
+
- Badge: ``
|
|
1016
|
+
|
|
1017
|
+
### CircleCI
|
|
1018
|
+
- File: `.circleci/config.yml`
|
|
1019
|
+
- View results: `https://app.circleci.com/pipelines/github/{user}/{repo}`
|
|
1020
|
+
- Badge: ``
|
|
1021
|
+
|
|
1022
|
+
## Error Handling
|
|
1023
|
+
|
|
1024
|
+
### If workflow file already exists
|
|
1025
|
+
|
|
1026
|
+
```bash
|
|
1027
|
+
if [ -f .github/workflows/ci.yml ]; then
|
|
1028
|
+
# Ask user if they want to overwrite
|
|
1029
|
+
```
|
|
1030
|
+
|
|
1031
|
+
```xml
|
|
1032
|
+
<invoke name="AskUserQuestion">
|
|
1033
|
+
<parameter name="questions">[{
|
|
1034
|
+
"question": "CI workflow already exists. Overwrite it?",
|
|
1035
|
+
"header": "Overwrite",
|
|
1036
|
+
"multiSelect": false,
|
|
1037
|
+
"options": [
|
|
1038
|
+
{
|
|
1039
|
+
"label": "Yes, overwrite",
|
|
1040
|
+
"description": "Replace existing workflow with new configuration"
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
"label": "No, skip",
|
|
1044
|
+
"description": "Keep existing workflow - don't make any changes"
|
|
1045
|
+
}
|
|
1046
|
+
]
|
|
1047
|
+
}]</parameter>
|
|
1048
|
+
</invoke>
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
```bash
|
|
1052
|
+
# If user selected "No, skip"
|
|
1053
|
+
echo "⏭️ Skipping CI configuration (file already exists)"
|
|
1054
|
+
exit 0
|
|
1055
|
+
fi
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
### If git remote not configured
|
|
1059
|
+
|
|
1060
|
+
```bash
|
|
1061
|
+
if ! git remote -v 2>/dev/null | grep -q origin; then
|
|
1062
|
+
echo "⚠️ Warning: Git remote not configured"
|
|
1063
|
+
echo " CI badge URLs will be placeholders"
|
|
1064
|
+
echo " Configure git remote first: /AgileFlow:configure (select Git Repository)"
|
|
1065
|
+
fi
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
## Rules
|
|
1069
|
+
|
|
1070
|
+
- Use AskUserQuestion for ALL user inputs (provider, commands, overwrite confirmation)
|
|
1071
|
+
- Detect project type and provide smart defaults
|
|
1072
|
+
- Show preview of workflow file before writing
|
|
1073
|
+
- Validate YAML syntax (no trailing commas, proper indentation)
|
|
1074
|
+
- Only include steps for commands user selected
|
|
1075
|
+
- Update CLAUDE.md with clear documentation
|
|
1076
|
+
- Print clear next steps (commit, push, check status)
|
|
1077
|
+
- Handle existing files gracefully (ask before overwriting)
|