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.
Files changed (176) hide show
  1. package/.claude/settings.local.json +35 -0
  2. package/.github/actions/calculate-version/action.yml +106 -0
  3. package/.github/actions/create-pr/action.yml +122 -0
  4. package/.github/actions/create-release/action.yml +74 -0
  5. package/.github/actions/create-tag/action.yml +94 -0
  6. package/.github/actions/detect-changes/action.yml +62 -0
  7. package/.github/actions/manage-branch/action.yml +113 -0
  8. package/.github/actions/promote-branch/action.yml +352 -0
  9. package/.github/example/workflows/job.analyze.code.yml +26 -0
  10. package/.github/example/workflows/job.analyze.docker.yml +32 -0
  11. package/.github/example/workflows/job.app.api.deploy.yml +127 -0
  12. package/.github/example/workflows/job.app.api.test.yml +102 -0
  13. package/.github/example/workflows/job.app.docs.deploy.yml +40 -0
  14. package/.github/example/workflows/job.app.docs.test.yml +50 -0
  15. package/.github/example/workflows/job.app.web.deploy.yml +96 -0
  16. package/.github/example/workflows/job.app.web.test.yml +49 -0
  17. package/.github/example/workflows/job.changes.yml +82 -0
  18. package/.github/example/workflows/job.create-pr.yml +96 -0
  19. package/.github/example/workflows/job.env-check.yml +43 -0
  20. package/.github/example/workflows/job.fast-forward.yml +103 -0
  21. package/.github/example/workflows/job.lint.yml +64 -0
  22. package/.github/example/workflows/job.pr-name.yml +70 -0
  23. package/.github/example/workflows/job.pr-squash-name.yml +27 -0
  24. package/.github/example/workflows/job.tag.yml +38 -0
  25. package/.github/example/workflows/job.version.yml +99 -0
  26. package/.github/example/workflows/lib.plugin-base.publish.yml +59 -0
  27. package/.github/example/workflows/pipe.yml +178 -0
  28. package/.github/example/workflows/scripts/fastforward.sh +51 -0
  29. package/.github/example/workflows/scripts/pipe-cleaner.sh +70 -0
  30. package/.github/scripts/fastforward.sh +51 -0
  31. package/.github/scripts/pipe-cleaner.sh +70 -0
  32. package/.github/workflows/pipeline.yml +220 -0
  33. package/.github/workflows/pr-title-check.yml +70 -0
  34. package/.github/workflows/publish.yml +39 -0
  35. package/.pipecraftrc.json +78 -0
  36. package/.release-it.cjs +71 -0
  37. package/PIPELINE_TESTING_PLAN.md +499 -0
  38. package/README.md +1101 -0
  39. package/TRUNK_FLOW_PLAN.md +401 -0
  40. package/assets/logo_banner.png +0 -0
  41. package/assets/logo_banner.webp +0 -0
  42. package/dist/cli/index.d.ts +3 -0
  43. package/dist/cli/index.d.ts.map +1 -0
  44. package/dist/cli/index.js +364 -0
  45. package/dist/cli/index.js.map +1 -0
  46. package/dist/generators/init.tpl.d.ts +3 -0
  47. package/dist/generators/init.tpl.d.ts.map +1 -0
  48. package/dist/generators/init.tpl.js +117 -0
  49. package/dist/generators/init.tpl.js.map +1 -0
  50. package/dist/generators/workflows.tpl.d.ts +7 -0
  51. package/dist/generators/workflows.tpl.d.ts.map +1 -0
  52. package/dist/generators/workflows.tpl.js +73 -0
  53. package/dist/generators/workflows.tpl.js.map +1 -0
  54. package/dist/templates/actions/calculate-version.yml.tpl.d.ts +3 -0
  55. package/dist/templates/actions/calculate-version.yml.tpl.d.ts.map +1 -0
  56. package/dist/templates/actions/calculate-version.yml.tpl.js +122 -0
  57. package/dist/templates/actions/calculate-version.yml.tpl.js.map +1 -0
  58. package/dist/templates/actions/create-pr.yml.tpl.d.ts +3 -0
  59. package/dist/templates/actions/create-pr.yml.tpl.d.ts.map +1 -0
  60. package/dist/templates/actions/create-pr.yml.tpl.js +145 -0
  61. package/dist/templates/actions/create-pr.yml.tpl.js.map +1 -0
  62. package/dist/templates/actions/create-tag.yml.tpl.d.ts +3 -0
  63. package/dist/templates/actions/create-tag.yml.tpl.d.ts.map +1 -0
  64. package/dist/templates/actions/create-tag.yml.tpl.js +111 -0
  65. package/dist/templates/actions/create-tag.yml.tpl.js.map +1 -0
  66. package/dist/templates/actions/detect-changes.yml.tpl.d.ts +3 -0
  67. package/dist/templates/actions/detect-changes.yml.tpl.d.ts.map +1 -0
  68. package/dist/templates/actions/detect-changes.yml.tpl.js +79 -0
  69. package/dist/templates/actions/detect-changes.yml.tpl.js.map +1 -0
  70. package/dist/templates/actions/manage-branch.yml.tpl.d.ts +3 -0
  71. package/dist/templates/actions/manage-branch.yml.tpl.d.ts.map +1 -0
  72. package/dist/templates/actions/manage-branch.yml.tpl.js +130 -0
  73. package/dist/templates/actions/manage-branch.yml.tpl.js.map +1 -0
  74. package/dist/templates/actions/promote-branch.yml.tpl.d.ts +3 -0
  75. package/dist/templates/actions/promote-branch.yml.tpl.d.ts.map +1 -0
  76. package/dist/templates/actions/promote-branch.yml.tpl.js +362 -0
  77. package/dist/templates/actions/promote-branch.yml.tpl.js.map +1 -0
  78. package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts +16 -0
  79. package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts.map +1 -0
  80. package/dist/templates/workflows/pipeline-path-based.yml.tpl.js +652 -0
  81. package/dist/templates/workflows/pipeline-path-based.yml.tpl.js.map +1 -0
  82. package/dist/types/index.d.ts +63 -0
  83. package/dist/types/index.d.ts.map +1 -0
  84. package/dist/types/index.js +2 -0
  85. package/dist/types/index.js.map +1 -0
  86. package/dist/utils/ast-path-operations.d.ts +287 -0
  87. package/dist/utils/ast-path-operations.d.ts.map +1 -0
  88. package/dist/utils/ast-path-operations.js +419 -0
  89. package/dist/utils/ast-path-operations.js.map +1 -0
  90. package/dist/utils/config.d.ts +3 -0
  91. package/dist/utils/config.d.ts.map +1 -0
  92. package/dist/utils/config.js +49 -0
  93. package/dist/utils/config.js.map +1 -0
  94. package/dist/utils/github-setup.d.ts +74 -0
  95. package/dist/utils/github-setup.d.ts.map +1 -0
  96. package/dist/utils/github-setup.js +418 -0
  97. package/dist/utils/github-setup.js.map +1 -0
  98. package/dist/utils/idempotency.d.ts +47 -0
  99. package/dist/utils/idempotency.d.ts.map +1 -0
  100. package/dist/utils/idempotency.js +176 -0
  101. package/dist/utils/idempotency.js.map +1 -0
  102. package/dist/utils/preflight.d.ts +55 -0
  103. package/dist/utils/preflight.d.ts.map +1 -0
  104. package/dist/utils/preflight.js +261 -0
  105. package/dist/utils/preflight.js.map +1 -0
  106. package/dist/utils/versioning.d.ts +41 -0
  107. package/dist/utils/versioning.d.ts.map +1 -0
  108. package/dist/utils/versioning.js +219 -0
  109. package/dist/utils/versioning.js.map +1 -0
  110. package/docs/USER_JOURNEY_ERRORS.md +352 -0
  111. package/eslint.config.js +77 -0
  112. package/examples/basic-config.json +41 -0
  113. package/examples/monorepo-config.json +49 -0
  114. package/examples/usage.md +289 -0
  115. package/package.json +58 -0
  116. package/scripts/debug-workflows.sh +339 -0
  117. package/scripts/parse-pipeline.js +29 -0
  118. package/scripts/test-job-order.cjs +140 -0
  119. package/scripts/validate-pipeline.cjs +379 -0
  120. package/scripts/verify-job-order.sh +30 -0
  121. package/src/cli/index.ts +414 -0
  122. package/src/generators/init.tpl.ts +126 -0
  123. package/src/generators/workflows.tpl.ts +80 -0
  124. package/src/templates/actions/calculate-version.yml.tpl.ts +124 -0
  125. package/src/templates/actions/create-pr.yml.tpl.ts +147 -0
  126. package/src/templates/actions/create-tag.yml.tpl.ts +112 -0
  127. package/src/templates/actions/detect-changes.yml.tpl.ts +87 -0
  128. package/src/templates/actions/manage-branch.yml.tpl.ts +132 -0
  129. package/src/templates/actions/promote-branch.yml.tpl.ts +364 -0
  130. package/src/templates/workflows/pipeline-path-based.yml.tpl.ts +706 -0
  131. package/src/types/index.ts +64 -0
  132. package/src/utils/README-ast-path-operations.md +390 -0
  133. package/src/utils/ast-path-operations.ts +581 -0
  134. package/src/utils/config.ts +64 -0
  135. package/src/utils/github-setup.ts +558 -0
  136. package/src/utils/idempotency.ts +215 -0
  137. package/src/utils/preflight.ts +306 -0
  138. package/src/utils/versioning.ts +244 -0
  139. package/tests/README.md +229 -0
  140. package/tests/TEST_STRUCTURE.md +256 -0
  141. package/tests/act/run-act-tests.sh +345 -0
  142. package/tests/debugging/debug-utils.ts +538 -0
  143. package/tests/debugging/debug-workflow.test.ts +339 -0
  144. package/tests/debugging/debug-workflows.sh +339 -0
  145. package/tests/debugging/iterative-debug.ts +652 -0
  146. package/tests/debugging/run-debug-tests.sh +431 -0
  147. package/tests/fixtures/basic-config.json +51 -0
  148. package/tests/fixtures/invalid-config.json +9 -0
  149. package/tests/fixtures/pipeline-generated.yml +235 -0
  150. package/tests/fixtures/pipeline-preserve-comments.yml +245 -0
  151. package/tests/fixtures/pipeline-user-modified.yml +245 -0
  152. package/tests/fixtures/test-config.json +58 -0
  153. package/tests/github-live/README.md +250 -0
  154. package/tests/github-local/JOB_WORKFLOW_TESTS.md +296 -0
  155. package/tests/github-local/README.md +240 -0
  156. package/tests/github-local/run-all-tests.sh +422 -0
  157. package/tests/github-local/test-job-workflows.sh +631 -0
  158. package/tests/github-local/test-pipeline-workflow.sh +440 -0
  159. package/tests/integration/generators.test.ts +578 -0
  160. package/tests/integration/path-based-template.test.ts +510 -0
  161. package/tests/integration/simple-path-based.test.ts +415 -0
  162. package/tests/setup.ts +56 -0
  163. package/tests/unit/ast-path-operations-extended.test.ts +302 -0
  164. package/tests/unit/cli.test.ts +541 -0
  165. package/tests/unit/config-extended.test.ts +412 -0
  166. package/tests/unit/config.test.ts +152 -0
  167. package/tests/unit/github-setup.test.ts +189 -0
  168. package/tests/unit/idempotency-isolated.test.ts +297 -0
  169. package/tests/unit/job-order.test.ts +157 -0
  170. package/tests/unit/pipeline-path-based.test.ts +511 -0
  171. package/tests/unit/validate-pipeline.test.ts +384 -0
  172. package/tests/unit/versioning-extended.test.ts +279 -0
  173. package/tests/unit/versioning.test.ts +241 -0
  174. package/tsconfig.debug.json +17 -0
  175. package/tsconfig.json +28 -0
  176. 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)