pipecraft 0.0.0-releaseit
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/.claude/settings.local.json +35 -0
- package/.github/actions/calculate-version/action.yml +106 -0
- package/.github/actions/create-pr/action.yml +122 -0
- package/.github/actions/create-release/action.yml +74 -0
- package/.github/actions/create-tag/action.yml +94 -0
- package/.github/actions/detect-changes/action.yml +62 -0
- package/.github/actions/manage-branch/action.yml +113 -0
- package/.github/actions/promote-branch/action.yml +352 -0
- package/.github/example/workflows/job.analyze.code.yml +26 -0
- package/.github/example/workflows/job.analyze.docker.yml +32 -0
- package/.github/example/workflows/job.app.api.deploy.yml +127 -0
- package/.github/example/workflows/job.app.api.test.yml +102 -0
- package/.github/example/workflows/job.app.docs.deploy.yml +40 -0
- package/.github/example/workflows/job.app.docs.test.yml +50 -0
- package/.github/example/workflows/job.app.web.deploy.yml +96 -0
- package/.github/example/workflows/job.app.web.test.yml +49 -0
- package/.github/example/workflows/job.changes.yml +82 -0
- package/.github/example/workflows/job.create-pr.yml +96 -0
- package/.github/example/workflows/job.env-check.yml +43 -0
- package/.github/example/workflows/job.fast-forward.yml +103 -0
- package/.github/example/workflows/job.lint.yml +64 -0
- package/.github/example/workflows/job.pr-name.yml +70 -0
- package/.github/example/workflows/job.pr-squash-name.yml +27 -0
- package/.github/example/workflows/job.tag.yml +38 -0
- package/.github/example/workflows/job.version.yml +99 -0
- package/.github/example/workflows/lib.plugin-base.publish.yml +59 -0
- package/.github/example/workflows/pipe.yml +178 -0
- package/.github/example/workflows/scripts/fastforward.sh +51 -0
- package/.github/example/workflows/scripts/pipe-cleaner.sh +70 -0
- package/.github/scripts/fastforward.sh +51 -0
- package/.github/scripts/pipe-cleaner.sh +70 -0
- package/.github/workflows/pipeline.yml +220 -0
- package/.github/workflows/pr-title-check.yml +70 -0
- package/.github/workflows/publish.yml +39 -0
- package/.pipecraftrc.json +78 -0
- package/.release-it.cjs +71 -0
- package/PIPELINE_TESTING_PLAN.md +499 -0
- package/README.md +1101 -0
- package/TRUNK_FLOW_PLAN.md +401 -0
- package/assets/logo_banner.png +0 -0
- package/assets/logo_banner.webp +0 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +364 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/generators/init.tpl.d.ts +3 -0
- package/dist/generators/init.tpl.d.ts.map +1 -0
- package/dist/generators/init.tpl.js +117 -0
- package/dist/generators/init.tpl.js.map +1 -0
- package/dist/generators/workflows.tpl.d.ts +7 -0
- package/dist/generators/workflows.tpl.d.ts.map +1 -0
- package/dist/generators/workflows.tpl.js +73 -0
- package/dist/generators/workflows.tpl.js.map +1 -0
- package/dist/templates/actions/calculate-version.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/calculate-version.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/calculate-version.yml.tpl.js +122 -0
- package/dist/templates/actions/calculate-version.yml.tpl.js.map +1 -0
- package/dist/templates/actions/create-pr.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/create-pr.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/create-pr.yml.tpl.js +145 -0
- package/dist/templates/actions/create-pr.yml.tpl.js.map +1 -0
- package/dist/templates/actions/create-tag.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/create-tag.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/create-tag.yml.tpl.js +111 -0
- package/dist/templates/actions/create-tag.yml.tpl.js.map +1 -0
- package/dist/templates/actions/detect-changes.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/detect-changes.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/detect-changes.yml.tpl.js +79 -0
- package/dist/templates/actions/detect-changes.yml.tpl.js.map +1 -0
- package/dist/templates/actions/manage-branch.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/manage-branch.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/manage-branch.yml.tpl.js +130 -0
- package/dist/templates/actions/manage-branch.yml.tpl.js.map +1 -0
- package/dist/templates/actions/promote-branch.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/promote-branch.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/promote-branch.yml.tpl.js +362 -0
- package/dist/templates/actions/promote-branch.yml.tpl.js.map +1 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts +16 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts.map +1 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.js +652 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.js.map +1 -0
- package/dist/types/index.d.ts +63 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/ast-path-operations.d.ts +287 -0
- package/dist/utils/ast-path-operations.d.ts.map +1 -0
- package/dist/utils/ast-path-operations.js +419 -0
- package/dist/utils/ast-path-operations.js.map +1 -0
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +49 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/github-setup.d.ts +74 -0
- package/dist/utils/github-setup.d.ts.map +1 -0
- package/dist/utils/github-setup.js +418 -0
- package/dist/utils/github-setup.js.map +1 -0
- package/dist/utils/idempotency.d.ts +47 -0
- package/dist/utils/idempotency.d.ts.map +1 -0
- package/dist/utils/idempotency.js +176 -0
- package/dist/utils/idempotency.js.map +1 -0
- package/dist/utils/preflight.d.ts +55 -0
- package/dist/utils/preflight.d.ts.map +1 -0
- package/dist/utils/preflight.js +261 -0
- package/dist/utils/preflight.js.map +1 -0
- package/dist/utils/versioning.d.ts +41 -0
- package/dist/utils/versioning.d.ts.map +1 -0
- package/dist/utils/versioning.js +219 -0
- package/dist/utils/versioning.js.map +1 -0
- package/docs/USER_JOURNEY_ERRORS.md +352 -0
- package/eslint.config.js +77 -0
- package/examples/basic-config.json +41 -0
- package/examples/monorepo-config.json +49 -0
- package/examples/usage.md +289 -0
- package/package.json +58 -0
- package/scripts/debug-workflows.sh +339 -0
- package/scripts/parse-pipeline.js +29 -0
- package/scripts/test-job-order.cjs +140 -0
- package/scripts/validate-pipeline.cjs +379 -0
- package/scripts/verify-job-order.sh +30 -0
- package/src/cli/index.ts +414 -0
- package/src/generators/init.tpl.ts +126 -0
- package/src/generators/workflows.tpl.ts +80 -0
- package/src/templates/actions/calculate-version.yml.tpl.ts +124 -0
- package/src/templates/actions/create-pr.yml.tpl.ts +147 -0
- package/src/templates/actions/create-tag.yml.tpl.ts +112 -0
- package/src/templates/actions/detect-changes.yml.tpl.ts +87 -0
- package/src/templates/actions/manage-branch.yml.tpl.ts +132 -0
- package/src/templates/actions/promote-branch.yml.tpl.ts +364 -0
- package/src/templates/workflows/pipeline-path-based.yml.tpl.ts +706 -0
- package/src/types/index.ts +64 -0
- package/src/utils/README-ast-path-operations.md +390 -0
- package/src/utils/ast-path-operations.ts +581 -0
- package/src/utils/config.ts +64 -0
- package/src/utils/github-setup.ts +558 -0
- package/src/utils/idempotency.ts +215 -0
- package/src/utils/preflight.ts +306 -0
- package/src/utils/versioning.ts +244 -0
- package/tests/README.md +229 -0
- package/tests/TEST_STRUCTURE.md +256 -0
- package/tests/act/run-act-tests.sh +345 -0
- package/tests/debugging/debug-utils.ts +538 -0
- package/tests/debugging/debug-workflow.test.ts +339 -0
- package/tests/debugging/debug-workflows.sh +339 -0
- package/tests/debugging/iterative-debug.ts +652 -0
- package/tests/debugging/run-debug-tests.sh +431 -0
- package/tests/fixtures/basic-config.json +51 -0
- package/tests/fixtures/invalid-config.json +9 -0
- package/tests/fixtures/pipeline-generated.yml +235 -0
- package/tests/fixtures/pipeline-preserve-comments.yml +245 -0
- package/tests/fixtures/pipeline-user-modified.yml +245 -0
- package/tests/fixtures/test-config.json +58 -0
- package/tests/github-live/README.md +250 -0
- package/tests/github-local/JOB_WORKFLOW_TESTS.md +296 -0
- package/tests/github-local/README.md +240 -0
- package/tests/github-local/run-all-tests.sh +422 -0
- package/tests/github-local/test-job-workflows.sh +631 -0
- package/tests/github-local/test-pipeline-workflow.sh +440 -0
- package/tests/integration/generators.test.ts +578 -0
- package/tests/integration/path-based-template.test.ts +510 -0
- package/tests/integration/simple-path-based.test.ts +415 -0
- package/tests/setup.ts +56 -0
- package/tests/unit/ast-path-operations-extended.test.ts +302 -0
- package/tests/unit/cli.test.ts +541 -0
- package/tests/unit/config-extended.test.ts +412 -0
- package/tests/unit/config.test.ts +152 -0
- package/tests/unit/github-setup.test.ts +189 -0
- package/tests/unit/idempotency-isolated.test.ts +297 -0
- package/tests/unit/job-order.test.ts +157 -0
- package/tests/unit/pipeline-path-based.test.ts +511 -0
- package/tests/unit/validate-pipeline.test.ts +384 -0
- package/tests/unit/versioning-extended.test.ts +279 -0
- package/tests/unit/versioning.test.ts +241 -0
- package/tsconfig.debug.json +17 -0
- package/tsconfig.json +28 -0
- package/vitest.config.ts +51 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Pipecraft Usage Examples
|
|
2
|
+
|
|
3
|
+
## Quick Start
|
|
4
|
+
|
|
5
|
+
### 1. Initialize Pipecraft
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Interactive setup
|
|
9
|
+
npx pipecraft init
|
|
10
|
+
|
|
11
|
+
# Or with options
|
|
12
|
+
npx pipecraft init --interactive
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Generate Workflows
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Generate GitHub Actions workflows
|
|
19
|
+
npx pipecraft generate
|
|
20
|
+
|
|
21
|
+
# Generate with custom output directory
|
|
22
|
+
npx pipecraft generate --output .github/workflows
|
|
23
|
+
|
|
24
|
+
# Dry run to see what would be generated
|
|
25
|
+
npx pipecraft generate --dry-run
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 3. Validate Configuration
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Validate your configuration
|
|
32
|
+
npx pipecraft validate
|
|
33
|
+
|
|
34
|
+
# Verify everything is set up correctly
|
|
35
|
+
npx pipecraft verify
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration Examples
|
|
39
|
+
|
|
40
|
+
### Basic Project
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"ciProvider": "github",
|
|
45
|
+
"mergeStrategy": "fast-forward",
|
|
46
|
+
"requireConventionalCommits": true,
|
|
47
|
+
"initialBranch": "develop",
|
|
48
|
+
"finalBranch": "main",
|
|
49
|
+
"branchFlow": ["develop", "staging", "main"],
|
|
50
|
+
"domains": {
|
|
51
|
+
"api": {
|
|
52
|
+
"paths": ["apps/api/**"],
|
|
53
|
+
"description": "API application changes"
|
|
54
|
+
},
|
|
55
|
+
"web": {
|
|
56
|
+
"paths": ["apps/web/**"],
|
|
57
|
+
"description": "Web application changes"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Monorepo Project
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"ciProvider": "github",
|
|
68
|
+
"mergeStrategy": "fast-forward",
|
|
69
|
+
"requireConventionalCommits": true,
|
|
70
|
+
"initialBranch": "develop",
|
|
71
|
+
"finalBranch": "main",
|
|
72
|
+
"branchFlow": ["develop", "staging", "main"],
|
|
73
|
+
"domains": {
|
|
74
|
+
"frontend": {
|
|
75
|
+
"paths": ["packages/frontend/**", "apps/web/**"],
|
|
76
|
+
"description": "Frontend application changes"
|
|
77
|
+
},
|
|
78
|
+
"backend": {
|
|
79
|
+
"paths": ["packages/backend/**", "apps/api/**"],
|
|
80
|
+
"description": "Backend application changes"
|
|
81
|
+
},
|
|
82
|
+
"shared": {
|
|
83
|
+
"paths": ["packages/shared/**", "libs/**"],
|
|
84
|
+
"description": "Shared library changes"
|
|
85
|
+
},
|
|
86
|
+
"mobile": {
|
|
87
|
+
"paths": ["packages/mobile/**", "apps/mobile/**"],
|
|
88
|
+
"description": "Mobile application changes"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Workflow Examples
|
|
95
|
+
|
|
96
|
+
### Generated GitHub Actions Workflows
|
|
97
|
+
|
|
98
|
+
After running `pipecraft generate`, you'll get:
|
|
99
|
+
|
|
100
|
+
- **`pipeline.yml`**: Main orchestration workflow
|
|
101
|
+
- **`job.changes.yml`**: Change detection workflow
|
|
102
|
+
- **`job.version.yml`**: Version calculation workflow
|
|
103
|
+
- **`job.tag.yml`**: Tag creation workflow
|
|
104
|
+
- **`job.createpr.yml`**: PR management workflow
|
|
105
|
+
- **`job.branch.yml`**: Branch operations workflow
|
|
106
|
+
- **`job.apps.yml`**: Application deployment workflow
|
|
107
|
+
|
|
108
|
+
### Example Pipeline Flow
|
|
109
|
+
|
|
110
|
+
1. **Push to `develop`**:
|
|
111
|
+
- Detects changes in domains
|
|
112
|
+
- Runs tests
|
|
113
|
+
- Fast-forwards to `staging` if tests pass
|
|
114
|
+
|
|
115
|
+
2. **Push to `staging`**:
|
|
116
|
+
- Calculates version bump
|
|
117
|
+
- Creates PR to `main` for non-patch releases
|
|
118
|
+
- Auto-fast-forwards to `main` for patch releases
|
|
119
|
+
|
|
120
|
+
3. **Push to `main`**:
|
|
121
|
+
- Creates version tags
|
|
122
|
+
- Deploys applications
|
|
123
|
+
- Updates documentation
|
|
124
|
+
|
|
125
|
+
## Advanced Usage
|
|
126
|
+
|
|
127
|
+
### Custom Domain Patterns
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"domains": {
|
|
132
|
+
"api": {
|
|
133
|
+
"paths": [
|
|
134
|
+
"apps/api/**",
|
|
135
|
+
"packages/backend/**",
|
|
136
|
+
"src/api/**"
|
|
137
|
+
],
|
|
138
|
+
"description": "API application changes"
|
|
139
|
+
},
|
|
140
|
+
"frontend": {
|
|
141
|
+
"paths": [
|
|
142
|
+
"apps/web/**",
|
|
143
|
+
"packages/frontend/**",
|
|
144
|
+
"src/components/**"
|
|
145
|
+
],
|
|
146
|
+
"description": "Frontend application changes"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Custom Branch Flow
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"branchFlow": [
|
|
157
|
+
"develop",
|
|
158
|
+
"test",
|
|
159
|
+
"staging",
|
|
160
|
+
"main"
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Custom Semver Rules
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"semver": {
|
|
170
|
+
"bumpRules": {
|
|
171
|
+
"feat": "minor",
|
|
172
|
+
"fix": "patch",
|
|
173
|
+
"breaking": "major",
|
|
174
|
+
"docs": "patch",
|
|
175
|
+
"style": "patch",
|
|
176
|
+
"refactor": "minor",
|
|
177
|
+
"perf": "minor",
|
|
178
|
+
"test": "patch"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## CLI Commands
|
|
185
|
+
|
|
186
|
+
### `pipecraft init`
|
|
187
|
+
Initialize a new Pipecraft configuration.
|
|
188
|
+
|
|
189
|
+
**Options:**
|
|
190
|
+
- `--force`: Overwrite existing configuration
|
|
191
|
+
- `--interactive`: Use interactive setup wizard
|
|
192
|
+
|
|
193
|
+
### `pipecraft generate`
|
|
194
|
+
Generate CI/CD workflows from configuration.
|
|
195
|
+
|
|
196
|
+
**Options:**
|
|
197
|
+
- `--output <path>`: Output directory for generated workflows
|
|
198
|
+
- `--dry-run`: Show what would be generated without writing files
|
|
199
|
+
|
|
200
|
+
### `pipecraft validate`
|
|
201
|
+
Validate the configuration file.
|
|
202
|
+
|
|
203
|
+
### `pipecraft verify`
|
|
204
|
+
Check if Pipecraft is properly set up.
|
|
205
|
+
|
|
206
|
+
### `pipecraft promote`
|
|
207
|
+
Promote current branch to next environment.
|
|
208
|
+
|
|
209
|
+
**Options:**
|
|
210
|
+
- `--force`: Force promotion even if checks fail
|
|
211
|
+
|
|
212
|
+
## Integration Examples
|
|
213
|
+
|
|
214
|
+
### With Existing Projects
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Initialize in existing project
|
|
218
|
+
cd my-existing-project
|
|
219
|
+
npx pipecraft init
|
|
220
|
+
|
|
221
|
+
# Generate workflows
|
|
222
|
+
npx pipecraft generate
|
|
223
|
+
|
|
224
|
+
# Commit the generated workflows
|
|
225
|
+
git add .github/workflows/
|
|
226
|
+
git commit -m "feat: add pipecraft workflows"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### With Monorepos
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Initialize with monorepo configuration
|
|
233
|
+
npx pipecraft init
|
|
234
|
+
# Select domains for your monorepo structure
|
|
235
|
+
|
|
236
|
+
# Generate workflows
|
|
237
|
+
npx pipecraft generate
|
|
238
|
+
|
|
239
|
+
# Verify setup
|
|
240
|
+
npx pipecraft verify
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### With GitLab
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Initialize with GitLab CI
|
|
247
|
+
npx pipecraft init
|
|
248
|
+
# Select "gitlab" as CI provider
|
|
249
|
+
|
|
250
|
+
# Generate GitLab CI pipeline
|
|
251
|
+
npx pipecraft generate
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Troubleshooting
|
|
255
|
+
|
|
256
|
+
### Common Issues
|
|
257
|
+
|
|
258
|
+
1. **Configuration not found**
|
|
259
|
+
```bash
|
|
260
|
+
# Make sure you're in the project root
|
|
261
|
+
# Check if .trunkflowrc.json exists
|
|
262
|
+
ls -la .trunkflowrc.json
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
2. **Workflows not generated**
|
|
266
|
+
```bash
|
|
267
|
+
# Validate configuration first
|
|
268
|
+
npx pipecraft validate
|
|
269
|
+
|
|
270
|
+
# Then generate workflows
|
|
271
|
+
npx pipecraft generate
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
3. **Permission issues**
|
|
275
|
+
```bash
|
|
276
|
+
# Make sure you have write permissions
|
|
277
|
+
# Check if .github/workflows directory exists
|
|
278
|
+
mkdir -p .github/workflows
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Debug Mode
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# Run with verbose output
|
|
285
|
+
npx pipecraft generate --verbose
|
|
286
|
+
|
|
287
|
+
# Dry run to see what would be generated
|
|
288
|
+
npx pipecraft generate --dry-run
|
|
289
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pipecraft",
|
|
3
|
+
"version": "0.0.0-releaseit",
|
|
4
|
+
"description": "CLI tool for managing trunk-based development workflows",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"pipecraft": "./dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsx src/cli/index.ts",
|
|
13
|
+
"test": "vitest",
|
|
14
|
+
"test:ui": "vitest --ui",
|
|
15
|
+
"test:run": "vitest run",
|
|
16
|
+
"test:coverage": "vitest run --coverage",
|
|
17
|
+
"test:watch": "vitest --watch",
|
|
18
|
+
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
|
19
|
+
"lint:fix": "eslint --fix . --ext .js,.jsx,.ts,.tsx",
|
|
20
|
+
"lint:strict": "eslint . --ext .js,.jsx,.ts,.tsx --max-warnings=0",
|
|
21
|
+
"format": "prettier --write '**/*.{js,jsx,ts,tsx,json,css,scss,md}'",
|
|
22
|
+
"format:check": "prettier --check '**/*.{js,jsx,ts,tsx,json,css,scss,md}'",
|
|
23
|
+
"validate:pipeline": "node scripts/validate-pipeline.cjs",
|
|
24
|
+
"pipecraft": "tsx src/cli/index.ts",
|
|
25
|
+
"init": "tsx src/cli/index.ts init --interactive",
|
|
26
|
+
"generate": "tsx src/cli/index.ts generate",
|
|
27
|
+
"verify": "tsx src/cli/index.ts verify"
|
|
28
|
+
},
|
|
29
|
+
"private": false,
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
32
|
+
"@eslint/js": "^9.24.0",
|
|
33
|
+
"@featherscloud/pinion": "^0.5.5",
|
|
34
|
+
"@release-it/conventional-changelog": "^10.0.0",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^8.30.1",
|
|
36
|
+
"@typescript-eslint/parser": "^8.30.1",
|
|
37
|
+
"@vitest/coverage-c8": "^0.33.0",
|
|
38
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
39
|
+
"@vitest/ui": "^2.1.8",
|
|
40
|
+
"c8": "^10.1.3",
|
|
41
|
+
"commander": "^14.0.1",
|
|
42
|
+
"conventional-changelog-angular": "latest",
|
|
43
|
+
"cosmiconfig": "^9.0.0",
|
|
44
|
+
"eslint": "^9.24.0",
|
|
45
|
+
"eslint-plugin-import": "^2.31.0",
|
|
46
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
47
|
+
"eslint-plugin-react": "^7.37.5",
|
|
48
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
49
|
+
"globals": "^16.0.0",
|
|
50
|
+
"prettier": "^2.8.8",
|
|
51
|
+
"release-it": "^18.1.2",
|
|
52
|
+
"vitest": "^2.1.8"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"dedent": "^1.7.0",
|
|
56
|
+
"yaml": "^2.8.1"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# GitHub Actions Workflow Debugging Script
|
|
4
|
+
# This script fetches workflow status, job details, and logs for debugging
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
REPO_OWNER="${GITHUB_REPOSITORY_OWNER:-$(git config --get remote.origin.url | sed 's/.*github.com[:/]\([^/]*\)\/\([^/]*\)\.git.*/\1/')}"
|
|
10
|
+
REPO_NAME="${GITHUB_REPOSITORY##*/:-$(git config --get remote.origin.url | sed 's/.*github.com[:/]\([^/]*\)\/\([^/]*\)\.git.*/\2/')}"
|
|
11
|
+
GITHUB_TOKEN="${GITHUB_TOKEN:-}"
|
|
12
|
+
API_BASE="https://api.github.com"
|
|
13
|
+
|
|
14
|
+
# Colors for output
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
BLUE='\033[0;34m'
|
|
19
|
+
PURPLE='\033[0;35m'
|
|
20
|
+
CYAN='\033[0;36m'
|
|
21
|
+
NC='\033[0m' # No Color
|
|
22
|
+
|
|
23
|
+
# Default values
|
|
24
|
+
WORKFLOW_NAME=""
|
|
25
|
+
BRANCH=""
|
|
26
|
+
LIMIT=10
|
|
27
|
+
OUTPUT_DIR="./debug-output"
|
|
28
|
+
VERBOSE=false
|
|
29
|
+
FETCH_LOGS=true
|
|
30
|
+
|
|
31
|
+
# Function to print colored output
|
|
32
|
+
print_status() {
|
|
33
|
+
local status=$1
|
|
34
|
+
local message=$2
|
|
35
|
+
|
|
36
|
+
case $status in
|
|
37
|
+
"SUCCESS") echo -e "${GREEN}✓${NC} $message" ;;
|
|
38
|
+
"FAILURE") echo -e "${RED}✗${NC} $message" ;;
|
|
39
|
+
"CANCELLED") echo -e "${YELLOW}⚠${NC} $message" ;;
|
|
40
|
+
"IN_PROGRESS") echo -e "${BLUE}⟳${NC} $message" ;;
|
|
41
|
+
"QUEUED") echo -e "${PURPLE}⏳${NC} $message" ;;
|
|
42
|
+
"SKIPPED") echo -e "${CYAN}⊘${NC} $message" ;;
|
|
43
|
+
*) echo -e "${YELLOW}?${NC} $message" ;;
|
|
44
|
+
esac
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Function to make GitHub API calls
|
|
48
|
+
github_api() {
|
|
49
|
+
local endpoint=$1
|
|
50
|
+
local method=${2:-GET}
|
|
51
|
+
|
|
52
|
+
if [[ -z "$GITHUB_TOKEN" ]]; then
|
|
53
|
+
echo -e "${RED}Error: GITHUB_TOKEN environment variable is required${NC}" >&2
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
curl -s -H "Authorization: token $GITHUB_TOKEN" \
|
|
58
|
+
-H "Accept: application/vnd.github.v3+json" \
|
|
59
|
+
-X "$method" \
|
|
60
|
+
"$API_BASE/repos/$REPO_OWNER/$REPO_NAME$endpoint"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Function to get workflow runs
|
|
64
|
+
get_workflow_runs() {
|
|
65
|
+
local workflow_name=$1
|
|
66
|
+
local branch=$2
|
|
67
|
+
local limit=$3
|
|
68
|
+
|
|
69
|
+
local endpoint="/actions/workflows/$workflow_name/runs"
|
|
70
|
+
local params="?per_page=$limit"
|
|
71
|
+
|
|
72
|
+
if [[ -n "$branch" ]]; then
|
|
73
|
+
params="${params}&branch=$branch"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
github_api "$endpoint$params"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Function to get workflow run details
|
|
80
|
+
get_workflow_run() {
|
|
81
|
+
local run_id=$1
|
|
82
|
+
github_api "/actions/runs/$run_id"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Function to get jobs for a workflow run
|
|
86
|
+
get_workflow_jobs() {
|
|
87
|
+
local run_id=$1
|
|
88
|
+
github_api "/actions/runs/$run_id/jobs"
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# Function to get job logs
|
|
92
|
+
get_job_logs() {
|
|
93
|
+
local run_id=$1
|
|
94
|
+
local job_id=$2
|
|
95
|
+
local output_file=$3
|
|
96
|
+
|
|
97
|
+
local endpoint="/actions/runs/$run_id/jobs/$job_id/logs"
|
|
98
|
+
|
|
99
|
+
if [[ -z "$GITHUB_TOKEN" ]]; then
|
|
100
|
+
echo -e "${RED}Error: GITHUB_TOKEN required for log download${NC}" >&2
|
|
101
|
+
return 1
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
curl -s -H "Authorization: token $GITHUB_TOKEN" \
|
|
105
|
+
-H "Accept: application/vnd.github.v3+json" \
|
|
106
|
+
"$API_BASE/repos/$REPO_OWNER/$REPO_NAME$endpoint" > "$output_file"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Function to analyze workflow failures
|
|
110
|
+
analyze_failures() {
|
|
111
|
+
local run_id=$1
|
|
112
|
+
local output_dir=$2
|
|
113
|
+
|
|
114
|
+
echo -e "${BLUE}Analyzing workflow failures for run $run_id...${NC}"
|
|
115
|
+
|
|
116
|
+
# Get workflow run details
|
|
117
|
+
local run_details=$(get_workflow_run "$run_id")
|
|
118
|
+
local run_status=$(echo "$run_details" | jq -r '.conclusion // .status')
|
|
119
|
+
local run_url=$(echo "$run_details" | jq -r '.html_url')
|
|
120
|
+
|
|
121
|
+
echo -e "${CYAN}Workflow Status:${NC} $run_status"
|
|
122
|
+
echo -e "${CYAN}Workflow URL:${NC} $run_url"
|
|
123
|
+
|
|
124
|
+
# Get jobs
|
|
125
|
+
local jobs=$(get_workflow_jobs "$run_id")
|
|
126
|
+
local failed_jobs=$(echo "$jobs" | jq -r '.jobs[] | select(.conclusion == "failure" or .conclusion == "cancelled") | .name')
|
|
127
|
+
|
|
128
|
+
if [[ -z "$failed_jobs" ]]; then
|
|
129
|
+
echo -e "${GREEN}No failed jobs found${NC}"
|
|
130
|
+
return 0
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
echo -e "${RED}Failed Jobs:${NC}"
|
|
134
|
+
echo "$failed_jobs" | while read -r job_name; do
|
|
135
|
+
echo -e " ${RED}•${NC} $job_name"
|
|
136
|
+
done
|
|
137
|
+
|
|
138
|
+
# Get detailed job information
|
|
139
|
+
echo "$jobs" | jq -r '.jobs[] | select(.conclusion == "failure" or .conclusion == "cancelled") | .id' | while read -r job_id; do
|
|
140
|
+
local job_info=$(echo "$jobs" | jq -r ".jobs[] | select(.id == $job_id)")
|
|
141
|
+
local job_name=$(echo "$job_info" | jq -r '.name')
|
|
142
|
+
local job_conclusion=$(echo "$job_info" | jq -r '.conclusion')
|
|
143
|
+
local job_url=$(echo "$job_info" | jq -r '.html_url')
|
|
144
|
+
|
|
145
|
+
echo -e "\n${YELLOW}Job: $job_name${NC}"
|
|
146
|
+
echo -e "${YELLOW}Status:${NC} $job_conclusion"
|
|
147
|
+
echo -e "${YELLOW}URL:${NC} $job_url"
|
|
148
|
+
|
|
149
|
+
# Get job steps
|
|
150
|
+
local steps=$(echo "$job_info" | jq -r '.steps[] | select(.conclusion == "failure") | "\(.name): \(.conclusion)"')
|
|
151
|
+
if [[ -n "$steps" ]]; then
|
|
152
|
+
echo -e "${YELLOW}Failed Steps:${NC}"
|
|
153
|
+
echo "$steps" | while read -r step; do
|
|
154
|
+
echo -e " ${RED}•${NC} $step"
|
|
155
|
+
done
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
# Download logs if requested
|
|
159
|
+
if [[ "$FETCH_LOGS" == "true" ]]; then
|
|
160
|
+
local log_file="$output_dir/job-${job_id}-logs.txt"
|
|
161
|
+
echo -e "${BLUE}Downloading logs for job $job_name...${NC}"
|
|
162
|
+
if get_job_logs "$run_id" "$job_id" "$log_file"; then
|
|
163
|
+
echo -e "${GREEN}Logs saved to: $log_file${NC}"
|
|
164
|
+
else
|
|
165
|
+
echo -e "${RED}Failed to download logs for job $job_name${NC}"
|
|
166
|
+
fi
|
|
167
|
+
fi
|
|
168
|
+
done
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# Function to create summary report
|
|
172
|
+
create_summary_report() {
|
|
173
|
+
local output_dir=$1
|
|
174
|
+
local report_file="$output_dir/debug-summary.md"
|
|
175
|
+
|
|
176
|
+
echo -e "${BLUE}Creating summary report...${NC}"
|
|
177
|
+
|
|
178
|
+
cat > "$report_file" << EOF
|
|
179
|
+
# GitHub Actions Debug Summary
|
|
180
|
+
|
|
181
|
+
Generated: $(date)
|
|
182
|
+
Repository: $REPO_OWNER/$REPO_NAME
|
|
183
|
+
Workflow: $WORKFLOW_NAME
|
|
184
|
+
Branch: ${BRANCH:-"all"}
|
|
185
|
+
|
|
186
|
+
## Recent Workflow Runs
|
|
187
|
+
|
|
188
|
+
EOF
|
|
189
|
+
|
|
190
|
+
# Get recent runs
|
|
191
|
+
local runs=$(get_workflow_runs "$WORKFLOW_NAME" "$BRANCH" "$LIMIT")
|
|
192
|
+
|
|
193
|
+
echo "$runs" | jq -r '.workflow_runs[] | "\(.id)|\(.status)|\(.conclusion)|\(.created_at)|\(.html_url)"' | while IFS='|' read -r run_id status conclusion created_at url; do
|
|
194
|
+
echo "### Run $run_id" >> "$report_file"
|
|
195
|
+
echo "- **Status**: $status" >> "$report_file"
|
|
196
|
+
echo "- **Conclusion**: $conclusion" >> "$report_file"
|
|
197
|
+
echo "- **Created**: $created_at" >> "$report_file"
|
|
198
|
+
echo "- **URL**: $url" >> "$report_file"
|
|
199
|
+
echo "" >> "$report_file"
|
|
200
|
+
done
|
|
201
|
+
|
|
202
|
+
echo -e "${GREEN}Summary report created: $report_file${NC}"
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# Function to show usage
|
|
206
|
+
show_usage() {
|
|
207
|
+
cat << EOF
|
|
208
|
+
Usage: $0 [OPTIONS]
|
|
209
|
+
|
|
210
|
+
GitHub Actions Workflow Debugging Script
|
|
211
|
+
|
|
212
|
+
OPTIONS:
|
|
213
|
+
-w, --workflow NAME Workflow name to debug (required)
|
|
214
|
+
-b, --branch BRANCH Branch to filter runs (optional)
|
|
215
|
+
-l, --limit NUMBER Number of recent runs to fetch (default: 10)
|
|
216
|
+
-o, --output DIR Output directory for logs and reports (default: ./debug-output)
|
|
217
|
+
-t, --token TOKEN GitHub token (or set GITHUB_TOKEN env var)
|
|
218
|
+
-v, --verbose Verbose output
|
|
219
|
+
--no-logs Don't download job logs
|
|
220
|
+
-h, --help Show this help message
|
|
221
|
+
|
|
222
|
+
EXAMPLES:
|
|
223
|
+
$0 -w "My Custom Pipeline" -b main -l 5
|
|
224
|
+
$0 -w "CI" --no-logs -o ./debug-logs
|
|
225
|
+
GITHUB_TOKEN=your_token $0 -w "Deploy" -v
|
|
226
|
+
|
|
227
|
+
ENVIRONMENT VARIABLES:
|
|
228
|
+
GITHUB_TOKEN GitHub personal access token
|
|
229
|
+
GITHUB_REPOSITORY_OWNER Repository owner (auto-detected from git)
|
|
230
|
+
GITHUB_REPOSITORY Repository name (auto-detected from git)
|
|
231
|
+
|
|
232
|
+
EOF
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
# Parse command line arguments
|
|
236
|
+
while [[ $# -gt 0 ]]; do
|
|
237
|
+
case $1 in
|
|
238
|
+
-w|--workflow)
|
|
239
|
+
WORKFLOW_NAME="$2"
|
|
240
|
+
shift 2
|
|
241
|
+
;;
|
|
242
|
+
-b|--branch)
|
|
243
|
+
BRANCH="$2"
|
|
244
|
+
shift 2
|
|
245
|
+
;;
|
|
246
|
+
-l|--limit)
|
|
247
|
+
LIMIT="$2"
|
|
248
|
+
shift 2
|
|
249
|
+
;;
|
|
250
|
+
-o|--output)
|
|
251
|
+
OUTPUT_DIR="$2"
|
|
252
|
+
shift 2
|
|
253
|
+
;;
|
|
254
|
+
-t|--token)
|
|
255
|
+
GITHUB_TOKEN="$2"
|
|
256
|
+
shift 2
|
|
257
|
+
;;
|
|
258
|
+
-v|--verbose)
|
|
259
|
+
VERBOSE=true
|
|
260
|
+
shift
|
|
261
|
+
;;
|
|
262
|
+
--no-logs)
|
|
263
|
+
FETCH_LOGS=false
|
|
264
|
+
shift
|
|
265
|
+
;;
|
|
266
|
+
-h|--help)
|
|
267
|
+
show_usage
|
|
268
|
+
exit 0
|
|
269
|
+
;;
|
|
270
|
+
*)
|
|
271
|
+
echo -e "${RED}Unknown option: $1${NC}" >&2
|
|
272
|
+
show_usage
|
|
273
|
+
exit 1
|
|
274
|
+
;;
|
|
275
|
+
esac
|
|
276
|
+
done
|
|
277
|
+
|
|
278
|
+
# Validate required parameters
|
|
279
|
+
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
280
|
+
echo -e "${RED}Error: Workflow name is required${NC}" >&2
|
|
281
|
+
show_usage
|
|
282
|
+
exit 1
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
if [[ -z "$GITHUB_TOKEN" ]]; then
|
|
286
|
+
echo -e "${RED}Error: GitHub token is required${NC}" >&2
|
|
287
|
+
echo -e "${YELLOW}Set GITHUB_TOKEN environment variable or use -t option${NC}"
|
|
288
|
+
exit 1
|
|
289
|
+
fi
|
|
290
|
+
|
|
291
|
+
# Check if jq is installed
|
|
292
|
+
if ! command -v jq &> /dev/null; then
|
|
293
|
+
echo -e "${RED}Error: jq is required but not installed${NC}" >&2
|
|
294
|
+
echo -e "${YELLOW}Install jq: brew install jq (macOS) or apt-get install jq (Ubuntu)${NC}"
|
|
295
|
+
exit 1
|
|
296
|
+
fi
|
|
297
|
+
|
|
298
|
+
# Create output directory
|
|
299
|
+
mkdir -p "$OUTPUT_DIR"
|
|
300
|
+
|
|
301
|
+
echo -e "${BLUE}GitHub Actions Workflow Debugger${NC}"
|
|
302
|
+
echo -e "${CYAN}Repository:${NC} $REPO_OWNER/$REPO_NAME"
|
|
303
|
+
echo -e "${CYAN}Workflow:${NC} $WORKFLOW_NAME"
|
|
304
|
+
echo -e "${CYAN}Branch:${NC} ${BRANCH:-"all"}"
|
|
305
|
+
echo -e "${CYAN}Output:${NC} $OUTPUT_DIR"
|
|
306
|
+
echo ""
|
|
307
|
+
|
|
308
|
+
# Get recent workflow runs
|
|
309
|
+
echo -e "${BLUE}Fetching recent workflow runs...${NC}"
|
|
310
|
+
runs=$(get_workflow_runs "$WORKFLOW_NAME" "$BRANCH" "$LIMIT")
|
|
311
|
+
|
|
312
|
+
if [[ "$runs" == "null" || $(echo "$runs" | jq '.workflow_runs | length') -eq 0 ]]; then
|
|
313
|
+
echo -e "${YELLOW}No workflow runs found${NC}"
|
|
314
|
+
exit 0
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
# Display recent runs
|
|
318
|
+
echo -e "${CYAN}Recent Workflow Runs:${NC}"
|
|
319
|
+
echo "$runs" | jq -r '.workflow_runs[] | "\(.id)|\(.status)|\(.conclusion)|\(.created_at)|\(.html_url)"' | while IFS='|' read -r run_id status conclusion created_at url; do
|
|
320
|
+
print_status "$conclusion" "Run $run_id ($status) - $created_at"
|
|
321
|
+
if [[ "$VERBOSE" == "true" ]]; then
|
|
322
|
+
echo " URL: $url"
|
|
323
|
+
fi
|
|
324
|
+
done
|
|
325
|
+
|
|
326
|
+
# Analyze failures
|
|
327
|
+
echo ""
|
|
328
|
+
echo -e "${BLUE}Analyzing failures...${NC}"
|
|
329
|
+
echo "$runs" | jq -r '.workflow_runs[] | select(.conclusion == "failure" or .conclusion == "cancelled") | .id' | while read -r run_id; do
|
|
330
|
+
analyze_failures "$run_id" "$OUTPUT_DIR"
|
|
331
|
+
done
|
|
332
|
+
|
|
333
|
+
# Create summary report
|
|
334
|
+
create_summary_report "$OUTPUT_DIR"
|
|
335
|
+
|
|
336
|
+
echo ""
|
|
337
|
+
echo -e "${GREEN}Debug analysis complete!${NC}"
|
|
338
|
+
echo -e "${CYAN}Output directory:${NC} $OUTPUT_DIR"
|
|
339
|
+
echo -e "${CYAN}Summary report:${NC} $OUTPUT_DIR/debug-summary.md"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { parse, parseDocument, stringify } from 'yaml'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
|
|
4
|
+
// Parse the pipeline.yml.backup file
|
|
5
|
+
const pipelineContent = fs.readFileSync('.github/workflows/pipeline.yml.backup', 'utf8')
|
|
6
|
+
|
|
7
|
+
// Parse as a document to get the full AST structure
|
|
8
|
+
const doc = parseDocument(pipelineContent)
|
|
9
|
+
|
|
10
|
+
console.log('=== PARSED DOCUMENT AST STRUCTURE ===')
|
|
11
|
+
console.log('Document contents AST:', doc.contents)
|
|
12
|
+
|
|
13
|
+
console.log('\n=== DOCUMENT PROPERTIES ===')
|
|
14
|
+
console.log('Directives:', doc.directives)
|
|
15
|
+
console.log('Errors:', doc.errors)
|
|
16
|
+
console.log('Warnings:', doc.warnings)
|
|
17
|
+
|
|
18
|
+
console.log('\n=== CONVERTED TO JS OBJECT ===')
|
|
19
|
+
const jsObject = doc.toJS()
|
|
20
|
+
console.log(JSON.stringify(jsObject, null, 2))
|
|
21
|
+
|
|
22
|
+
// Save the parsed structure to a file for manipulation
|
|
23
|
+
fs.writeFileSync('pipeline-structure.json', JSON.stringify(jsObject, null, 2))
|
|
24
|
+
console.log('\n=== SAVED TO pipeline-structure.json ===')
|
|
25
|
+
|
|
26
|
+
// Test converting back to YAML
|
|
27
|
+
const backToYaml = stringify(jsObject, { indent: 2 })
|
|
28
|
+
console.log('\n=== CONVERTED BACK TO YAML ===')
|
|
29
|
+
console.log(backToYaml)
|