pipecraft 0.0.0-releaseit → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +126 -108
  2. package/dist/cli/index.d.ts +69 -0
  3. package/dist/cli/index.d.ts.map +1 -1
  4. package/dist/cli/index.js +94 -22
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/generators/init.tpl.d.ts +70 -0
  7. package/dist/generators/init.tpl.d.ts.map +1 -1
  8. package/dist/generators/init.tpl.js +100 -8
  9. package/dist/generators/init.tpl.js.map +1 -1
  10. package/dist/generators/workflows.tpl.d.ts +86 -0
  11. package/dist/generators/workflows.tpl.d.ts.map +1 -1
  12. package/dist/generators/workflows.tpl.js +101 -9
  13. package/dist/generators/workflows.tpl.js.map +1 -1
  14. package/dist/templates/actions/calculate-version.yml.tpl.d.ts +47 -0
  15. package/dist/templates/actions/calculate-version.yml.tpl.d.ts.map +1 -1
  16. package/dist/templates/actions/calculate-version.yml.tpl.js +72 -3
  17. package/dist/templates/actions/calculate-version.yml.tpl.js.map +1 -1
  18. package/dist/templates/actions/create-pr.yml.tpl.d.ts +14 -0
  19. package/dist/templates/actions/create-pr.yml.tpl.d.ts.map +1 -1
  20. package/dist/templates/actions/create-pr.yml.tpl.js +22 -2
  21. package/dist/templates/actions/create-pr.yml.tpl.js.map +1 -1
  22. package/dist/templates/actions/create-release.yml.tpl.d.ts +18 -0
  23. package/dist/templates/actions/create-release.yml.tpl.d.ts.map +1 -0
  24. package/dist/templates/actions/create-release.yml.tpl.js +141 -0
  25. package/dist/templates/actions/create-release.yml.tpl.js.map +1 -0
  26. package/dist/templates/actions/create-tag.yml.tpl.d.ts +14 -0
  27. package/dist/templates/actions/create-tag.yml.tpl.d.ts.map +1 -1
  28. package/dist/templates/actions/create-tag.yml.tpl.js +22 -2
  29. package/dist/templates/actions/create-tag.yml.tpl.js.map +1 -1
  30. package/dist/templates/actions/detect-changes.yml.tpl.d.ts +70 -0
  31. package/dist/templates/actions/detect-changes.yml.tpl.d.ts.map +1 -1
  32. package/dist/templates/actions/detect-changes.yml.tpl.js +98 -2
  33. package/dist/templates/actions/detect-changes.yml.tpl.js.map +1 -1
  34. package/dist/templates/actions/manage-branch.yml.tpl.d.ts +14 -0
  35. package/dist/templates/actions/manage-branch.yml.tpl.d.ts.map +1 -1
  36. package/dist/templates/actions/manage-branch.yml.tpl.js +22 -2
  37. package/dist/templates/actions/manage-branch.yml.tpl.js.map +1 -1
  38. package/dist/templates/actions/promote-branch.yml.tpl.d.ts +14 -0
  39. package/dist/templates/actions/promote-branch.yml.tpl.d.ts.map +1 -1
  40. package/dist/templates/actions/promote-branch.yml.tpl.js +50 -7
  41. package/dist/templates/actions/promote-branch.yml.tpl.js.map +1 -1
  42. package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts +114 -1
  43. package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts.map +1 -1
  44. package/dist/templates/workflows/pipeline-path-based.yml.tpl.js +479 -74
  45. package/dist/templates/workflows/pipeline-path-based.yml.tpl.js.map +1 -1
  46. package/dist/types/index.d.ts +231 -8
  47. package/dist/types/index.d.ts.map +1 -1
  48. package/dist/types/index.js +9 -0
  49. package/dist/types/index.js.map +1 -1
  50. package/dist/utils/ast-path-operations.d.ts.map +1 -1
  51. package/dist/utils/ast-path-operations.js +24 -11
  52. package/dist/utils/ast-path-operations.js.map +1 -1
  53. package/dist/utils/config.d.ts +63 -0
  54. package/dist/utils/config.d.ts.map +1 -1
  55. package/dist/utils/config.js +71 -0
  56. package/dist/utils/config.js.map +1 -1
  57. package/dist/utils/github-setup.d.ts +323 -2
  58. package/dist/utils/github-setup.d.ts.map +1 -1
  59. package/dist/utils/github-setup.js +551 -23
  60. package/dist/utils/github-setup.js.map +1 -1
  61. package/dist/utils/idempotency.d.ts +147 -7
  62. package/dist/utils/idempotency.d.ts.map +1 -1
  63. package/dist/utils/idempotency.js +143 -15
  64. package/dist/utils/idempotency.js.map +1 -1
  65. package/dist/utils/logger.d.ts +134 -0
  66. package/dist/utils/logger.d.ts.map +1 -0
  67. package/dist/utils/logger.js +153 -0
  68. package/dist/utils/logger.js.map +1 -0
  69. package/dist/utils/preflight.d.ts +223 -12
  70. package/dist/utils/preflight.d.ts.map +1 -1
  71. package/dist/utils/preflight.js +216 -16
  72. package/dist/utils/preflight.js.map +1 -1
  73. package/dist/utils/versioning.d.ts +160 -8
  74. package/dist/utils/versioning.d.ts.map +1 -1
  75. package/dist/utils/versioning.js +179 -15
  76. package/dist/utils/versioning.js.map +1 -1
  77. package/package.json +26 -5
  78. package/.claude/settings.local.json +0 -35
  79. package/.github/actions/calculate-version/action.yml +0 -106
  80. package/.github/actions/create-pr/action.yml +0 -122
  81. package/.github/actions/create-release/action.yml +0 -74
  82. package/.github/actions/create-tag/action.yml +0 -94
  83. package/.github/actions/detect-changes/action.yml +0 -62
  84. package/.github/actions/manage-branch/action.yml +0 -113
  85. package/.github/actions/promote-branch/action.yml +0 -352
  86. package/.github/example/workflows/job.analyze.code.yml +0 -26
  87. package/.github/example/workflows/job.analyze.docker.yml +0 -32
  88. package/.github/example/workflows/job.app.api.deploy.yml +0 -127
  89. package/.github/example/workflows/job.app.api.test.yml +0 -102
  90. package/.github/example/workflows/job.app.docs.deploy.yml +0 -40
  91. package/.github/example/workflows/job.app.docs.test.yml +0 -50
  92. package/.github/example/workflows/job.app.web.deploy.yml +0 -96
  93. package/.github/example/workflows/job.app.web.test.yml +0 -49
  94. package/.github/example/workflows/job.changes.yml +0 -82
  95. package/.github/example/workflows/job.create-pr.yml +0 -96
  96. package/.github/example/workflows/job.env-check.yml +0 -43
  97. package/.github/example/workflows/job.fast-forward.yml +0 -103
  98. package/.github/example/workflows/job.lint.yml +0 -64
  99. package/.github/example/workflows/job.pr-name.yml +0 -70
  100. package/.github/example/workflows/job.pr-squash-name.yml +0 -27
  101. package/.github/example/workflows/job.tag.yml +0 -38
  102. package/.github/example/workflows/job.version.yml +0 -99
  103. package/.github/example/workflows/lib.plugin-base.publish.yml +0 -59
  104. package/.github/example/workflows/pipe.yml +0 -178
  105. package/.github/example/workflows/scripts/fastforward.sh +0 -51
  106. package/.github/example/workflows/scripts/pipe-cleaner.sh +0 -70
  107. package/.github/scripts/fastforward.sh +0 -51
  108. package/.github/scripts/pipe-cleaner.sh +0 -70
  109. package/.github/workflows/pipeline.yml +0 -220
  110. package/.github/workflows/pr-title-check.yml +0 -70
  111. package/.github/workflows/publish.yml +0 -39
  112. package/.pipecraftrc.json +0 -78
  113. package/.release-it.cjs +0 -71
  114. package/PIPELINE_TESTING_PLAN.md +0 -499
  115. package/TRUNK_FLOW_PLAN.md +0 -401
  116. package/assets/logo_banner.png +0 -0
  117. package/assets/logo_banner.webp +0 -0
  118. package/docs/USER_JOURNEY_ERRORS.md +0 -352
  119. package/eslint.config.js +0 -77
  120. package/examples/basic-config.json +0 -41
  121. package/examples/monorepo-config.json +0 -49
  122. package/examples/usage.md +0 -289
  123. package/scripts/debug-workflows.sh +0 -339
  124. package/scripts/parse-pipeline.js +0 -29
  125. package/scripts/test-job-order.cjs +0 -140
  126. package/scripts/validate-pipeline.cjs +0 -379
  127. package/scripts/verify-job-order.sh +0 -30
  128. package/src/cli/index.ts +0 -414
  129. package/src/generators/init.tpl.ts +0 -126
  130. package/src/generators/workflows.tpl.ts +0 -80
  131. package/src/templates/actions/calculate-version.yml.tpl.ts +0 -124
  132. package/src/templates/actions/create-pr.yml.tpl.ts +0 -147
  133. package/src/templates/actions/create-tag.yml.tpl.ts +0 -112
  134. package/src/templates/actions/detect-changes.yml.tpl.ts +0 -87
  135. package/src/templates/actions/manage-branch.yml.tpl.ts +0 -132
  136. package/src/templates/actions/promote-branch.yml.tpl.ts +0 -364
  137. package/src/templates/workflows/pipeline-path-based.yml.tpl.ts +0 -706
  138. package/src/types/index.ts +0 -64
  139. package/src/utils/README-ast-path-operations.md +0 -390
  140. package/src/utils/ast-path-operations.ts +0 -581
  141. package/src/utils/config.ts +0 -64
  142. package/src/utils/github-setup.ts +0 -558
  143. package/src/utils/idempotency.ts +0 -215
  144. package/src/utils/preflight.ts +0 -306
  145. package/src/utils/versioning.ts +0 -244
  146. package/tests/README.md +0 -229
  147. package/tests/TEST_STRUCTURE.md +0 -256
  148. package/tests/act/run-act-tests.sh +0 -345
  149. package/tests/debugging/debug-utils.ts +0 -538
  150. package/tests/debugging/debug-workflow.test.ts +0 -339
  151. package/tests/debugging/debug-workflows.sh +0 -339
  152. package/tests/debugging/iterative-debug.ts +0 -652
  153. package/tests/debugging/run-debug-tests.sh +0 -431
  154. package/tests/fixtures/basic-config.json +0 -51
  155. package/tests/fixtures/invalid-config.json +0 -9
  156. package/tests/fixtures/pipeline-generated.yml +0 -235
  157. package/tests/fixtures/pipeline-preserve-comments.yml +0 -245
  158. package/tests/fixtures/pipeline-user-modified.yml +0 -245
  159. package/tests/fixtures/test-config.json +0 -58
  160. package/tests/github-live/README.md +0 -250
  161. package/tests/github-local/JOB_WORKFLOW_TESTS.md +0 -296
  162. package/tests/github-local/README.md +0 -240
  163. package/tests/github-local/run-all-tests.sh +0 -422
  164. package/tests/github-local/test-job-workflows.sh +0 -631
  165. package/tests/github-local/test-pipeline-workflow.sh +0 -440
  166. package/tests/integration/generators.test.ts +0 -578
  167. package/tests/integration/path-based-template.test.ts +0 -510
  168. package/tests/integration/simple-path-based.test.ts +0 -415
  169. package/tests/setup.ts +0 -56
  170. package/tests/unit/ast-path-operations-extended.test.ts +0 -302
  171. package/tests/unit/cli.test.ts +0 -541
  172. package/tests/unit/config-extended.test.ts +0 -412
  173. package/tests/unit/config.test.ts +0 -152
  174. package/tests/unit/github-setup.test.ts +0 -189
  175. package/tests/unit/idempotency-isolated.test.ts +0 -297
  176. package/tests/unit/job-order.test.ts +0 -157
  177. package/tests/unit/pipeline-path-based.test.ts +0 -511
  178. package/tests/unit/validate-pipeline.test.ts +0 -384
  179. package/tests/unit/versioning-extended.test.ts +0 -279
  180. package/tests/unit/versioning.test.ts +0 -241
  181. package/tsconfig.debug.json +0 -17
  182. package/tsconfig.json +0 -28
  183. package/vitest.config.ts +0 -51
@@ -1,510 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
- import { writeFileSync, existsSync, rmSync, readFileSync, mkdirSync } from 'fs'
3
- import { join } from 'path'
4
- import { TEST_DIR, FIXTURES_DIR } from '../setup'
5
- import { parse } from 'yaml'
6
-
7
- // Import the internal function directly for testing
8
- import { createPathBasedPipeline } from '../../src/templates/workflows/pipeline-path-based.yml.tpl'
9
-
10
- describe('Path-Based Template Generation Tests', () => {
11
- const testConfigPath = join(TEST_DIR, 'custom-pipecraftrc.json')
12
- const testPipelinePath = join(TEST_DIR, 'custom-pipeline.yml')
13
- const outputPath = join(TEST_DIR, '.github/workflows/pipeline.yml')
14
-
15
- beforeEach(() => {
16
- // Clean up test files
17
- const filesToClean = [testConfigPath, testPipelinePath, outputPath, '.pipecraft-cache.json']
18
- filesToClean.forEach(file => {
19
- const fullPath = join(TEST_DIR, file)
20
- if (existsSync(fullPath)) {
21
- rmSync(fullPath, { recursive: true, force: true })
22
- }
23
- })
24
-
25
- // Create .github/workflows directory
26
- mkdirSync(join(TEST_DIR, '.github/workflows'), { recursive: true })
27
- })
28
-
29
- afterEach(() => {
30
- // Clean up after each test
31
- const filesToClean = [testConfigPath, testPipelinePath, outputPath, '.pipecraft-cache.json']
32
- filesToClean.forEach(file => {
33
- const fullPath = join(TEST_DIR, file)
34
- if (existsSync(fullPath)) {
35
- rmSync(fullPath, { recursive: true, force: true })
36
- }
37
- })
38
- })
39
-
40
- describe('Custom Config and Pipeline Files', () => {
41
- it('should generate pipeline with custom config file containing unexpected variables', async () => {
42
- // Create custom config with unexpected variables (alpha, beta, gamma, delta, epsilon)
43
- const customConfig = {
44
- ciProvider: 'github',
45
- mergeStrategy: 'fast-forward',
46
- requireConventionalCommits: true,
47
- initialBranch: 'alpha',
48
- finalBranch: 'epsilon',
49
- branchFlow: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
50
- semver: {
51
- bumpRules: {
52
- feat: 'minor',
53
- fix: 'patch',
54
- breaking: 'major'
55
- }
56
- },
57
- actions: {
58
- onDevelopMerge: ['runTests', 'fastForwardToStaging'],
59
- onStagingMerge: ['runTests', 'calculateVersion', 'createOrFastForwardToMain']
60
- },
61
- domains: {
62
- 'fake-domain1': {
63
- paths: ['apps/fake-domain1/**'],
64
- description: 'fake-domain1 application changes'
65
- },
66
- 'fake-domain2': {
67
- paths: ['apps/fake-domain2/**'],
68
- description: 'fake-domain2 application changes'
69
- },
70
- 'fake-domain3': {
71
- paths: ['libs/fake-domain3/**'],
72
- description: 'fake-domain3 application changes'
73
- },
74
- 'fake-domain4': {
75
- paths: ['.github/workflows/fake-domain4/**'],
76
- description: 'fake-domain4 application changes'
77
- }
78
- }
79
- }
80
-
81
- writeFileSync(testConfigPath, JSON.stringify(customConfig, null, 2))
82
-
83
- // Create context with custom config
84
- const ctx = {
85
- ...customConfig,
86
- cwd: TEST_DIR,
87
- force: true
88
- }
89
-
90
- // Generate pipeline
91
- const result = createPathBasedPipeline(ctx)
92
-
93
- expect(result.yamlContent).toBeDefined()
94
- expect(result.mergeStatus).toBe('overwritten')
95
-
96
- // Parse generated YAML to verify structure
97
- const parsedYaml = parse(result.yamlContent)
98
- expect(parsedYaml).toBeDefined()
99
- expect(parsedYaml.name).toBe('Pipeline')
100
- expect(parsedYaml.on).toBeDefined()
101
- expect(parsedYaml.jobs).toBeDefined()
102
-
103
- // Verify workflow inputs are set correctly
104
- expect(parsedYaml.on.workflow_call?.inputs?.version).toBeDefined()
105
- expect(parsedYaml.on.workflow_call?.inputs?.baseRef).toBeDefined()
106
-
107
- // Verify branch configuration uses custom branch flow
108
- expect(parsedYaml.on.pull_request?.branches).toContain('alpha')
109
- expect(parsedYaml.on.pull_request?.branches).toContain('beta')
110
- expect(parsedYaml.on.pull_request?.branches).toContain('gamma')
111
- expect(parsedYaml.on.pull_request?.branches).toContain('delta')
112
- expect(parsedYaml.on.pull_request?.branches).toContain('epsilon')
113
-
114
- // Verify core jobs exist
115
- expect(parsedYaml.jobs.changes).toBeDefined()
116
- expect(parsedYaml.jobs.version).toBeDefined()
117
- expect(parsedYaml.jobs.tag).toBeDefined()
118
- expect(parsedYaml.jobs.createpr).toBeDefined()
119
- expect(parsedYaml.jobs.branch).toBeDefined()
120
-
121
- // Verify version job uses custom initial branch
122
- expect(parsedYaml.jobs.version.if).toContain('alpha')
123
- expect(parsedYaml.jobs.tag.if).toContain('alpha')
124
-
125
- // Verify createpr job excludes custom final branch
126
- expect(parsedYaml.jobs.createpr.if).toContain('epsilon')
127
- })
128
-
129
- it('should merge with existing pipeline file containing user customizations', async () => {
130
- // Create custom config
131
- const customConfig = {
132
- ciProvider: 'github',
133
- mergeStrategy: 'fast-forward',
134
- requireConventionalCommits: true,
135
- initialBranch: 'alpha',
136
- finalBranch: 'epsilon',
137
- branchFlow: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
138
- semver: {
139
- bumpRules: {
140
- feat: 'minor',
141
- fix: 'patch',
142
- breaking: 'major'
143
- }
144
- },
145
- actions: {
146
- onDevelopMerge: ['runTests', 'fastForwardToStaging'],
147
- onStagingMerge: ['runTests', 'calculateVersion', 'createOrFastForwardToMain']
148
- },
149
- domains: {
150
- 'fake-domain1': {
151
- paths: ['apps/fake-domain1/**'],
152
- description: 'fake-domain1 application changes'
153
- }
154
- }
155
- }
156
-
157
- // Create existing pipeline with user customizations (similar to pipeline-user-modified.yml)
158
- const existingPipeline = {
159
- name: "USER NAME",
160
- on: {
161
- pull_request: {
162
- paths: ['**/*.yml', '**/*.yaml', '**/*.json', '**/*.ts', '**/*.js', '**/*.tsx'],
163
- branches: ['develop', 'feature']
164
- },
165
- workflow_call: {
166
- inputs: {
167
- fakevar1: {
168
- description: 'The fake version to deploy',
169
- required: false,
170
- type: 'string'
171
- },
172
- version: {
173
- description: 'The version to deploy',
174
- required: false,
175
- type: 'string'
176
- },
177
- fakevar2: {
178
- description: 'The fake version to deploy',
179
- required: false,
180
- type: 'string'
181
- }
182
- },
183
- outputs: {
184
- fakevar3: {
185
- value: 'fakevalue3'
186
- },
187
- fakevar4: {
188
- value: 'fakevalue4'
189
- }
190
- }
191
- }
192
- },
193
- jobs: {
194
- 'fake-job-1': {
195
- runs_on: 'ubuntu-latest',
196
- steps: [
197
- {
198
- name: 'Fake Job',
199
- run: 'echo "Running fake job"'
200
- }
201
- ]
202
- },
203
- changes: {
204
- runs_on: 'ubuntu-latest',
205
- steps: [
206
- {
207
- uses: './.github/actions/detect-changes',
208
- with: {
209
- baseRef: '${{ inputs.baseRef || \'main\' }}'
210
- }
211
- }
212
- ]
213
- },
214
- 'fake-job-2': {
215
- runs_on: 'ubuntu-latest',
216
- steps: [
217
- {
218
- name: 'Fake Job',
219
- run: 'echo "Running fake job"'
220
- }
221
- ]
222
- }
223
- }
224
- }
225
-
226
- // Create context with existing pipeline
227
- const ctx = {
228
- ...customConfig,
229
- existingPipeline,
230
- cwd: TEST_DIR,
231
- force: true
232
- }
233
-
234
- // Generate pipeline
235
- const result = createPathBasedPipeline(ctx)
236
-
237
- expect(result.yamlContent).toBeDefined()
238
- expect(result.mergeStatus).toBe('merged')
239
-
240
- // Parse generated YAML to verify merging
241
- const parsedYaml = parse(result.yamlContent)
242
- expect(parsedYaml).toBeDefined()
243
-
244
- // Verify user customizations are preserved
245
- expect(parsedYaml.name).toBe('USER NAME')
246
- expect(parsedYaml.on.pull_request.paths).toContain('**/*.yml')
247
- expect(parsedYaml.on.pull_request.branches).toContain('develop')
248
- expect(parsedYaml.on.pull_request.branches).toContain('feature')
249
-
250
- // Verify user inputs are preserved and required inputs are added
251
- expect(parsedYaml.on.workflow_call.inputs.fakevar1).toBeDefined()
252
- expect(parsedYaml.on.workflow_call.inputs.version).toBeDefined()
253
- expect(parsedYaml.on.workflow_call.inputs.fakevar2).toBeDefined()
254
- expect(parsedYaml.on.workflow_call.inputs.baseRef).toBeDefined()
255
-
256
- // Verify user outputs are preserved
257
- expect(parsedYaml.on.workflow_call.outputs.fakevar3).toBeDefined()
258
- expect(parsedYaml.on.workflow_call.outputs.fakevar4).toBeDefined()
259
-
260
- // Verify user jobs are preserved
261
- expect(parsedYaml.jobs['fake-job-1']).toBeDefined()
262
- expect(parsedYaml.jobs['fake-job-2']).toBeDefined()
263
-
264
- // Verify core Pipecraft jobs are updated/overwritten
265
- expect(parsedYaml.jobs.changes).toBeDefined()
266
- expect(parsedYaml.jobs.version).toBeDefined()
267
- expect(parsedYaml.jobs.tag).toBeDefined()
268
- expect(parsedYaml.jobs.createpr).toBeDefined()
269
- expect(parsedYaml.jobs.branch).toBeDefined()
270
-
271
- // Verify branch configuration is merged (user branches + template branches)
272
- expect(parsedYaml.on.pull_request.branches).toContain('develop')
273
- expect(parsedYaml.on.pull_request.branches).toContain('feature')
274
- expect(parsedYaml.on.pull_request.branches).toContain('alpha')
275
- expect(parsedYaml.on.pull_request.branches).toContain('beta')
276
- expect(parsedYaml.on.pull_request.branches).toContain('gamma')
277
- expect(parsedYaml.on.pull_request.branches).toContain('delta')
278
- expect(parsedYaml.on.pull_request.branches).toContain('epsilon')
279
- })
280
-
281
- it('should handle missing existing pipeline gracefully', async () => {
282
- const customConfig = {
283
- ciProvider: 'github',
284
- mergeStrategy: 'fast-forward',
285
- requireConventionalCommits: true,
286
- initialBranch: 'alpha',
287
- finalBranch: 'epsilon',
288
- branchFlow: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
289
- semver: {
290
- bumpRules: {
291
- feat: 'minor',
292
- fix: 'patch',
293
- breaking: 'major'
294
- }
295
- },
296
- actions: {
297
- onDevelopMerge: ['runTests', 'fastForwardToStaging'],
298
- onStagingMerge: ['runTests', 'calculateVersion', 'createOrFastForwardToMain']
299
- },
300
- domains: {
301
- 'fake-domain1': {
302
- paths: ['apps/fake-domain1/**'],
303
- description: 'fake-domain1 application changes'
304
- }
305
- }
306
- }
307
-
308
- // Create context without existing pipeline
309
- const ctx = {
310
- ...customConfig,
311
- cwd: TEST_DIR,
312
- force: true
313
- }
314
-
315
- // Generate pipeline
316
- const result = createPathBasedPipeline(ctx)
317
-
318
- expect(result.yamlContent).toBeDefined()
319
- expect(result.mergeStatus).toBe('overwritten')
320
-
321
- // Parse generated YAML to verify structure
322
- const parsedYaml = parse(result.yamlContent)
323
- expect(parsedYaml).toBeDefined()
324
- expect(parsedYaml.name).toBe('Pipeline')
325
- expect(parsedYaml.jobs).toBeDefined()
326
- })
327
- })
328
-
329
- describe('Path Operations Validation', () => {
330
- it('should correctly apply set operations for workflow inputs', async () => {
331
- const ctx = {
332
- ciProvider: 'github',
333
- mergeStrategy: 'fast-forward',
334
- requireConventionalCommits: true,
335
- initialBranch: 'alpha',
336
- finalBranch: 'epsilon',
337
- branchFlow: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
338
- semver: { bumpRules: { feat: 'minor', fix: 'patch', breaking: 'major' } },
339
- actions: { onDevelopMerge: ['runTests'], onStagingMerge: ['runTests'] },
340
- domains: { 'fake-domain1': { paths: ['apps/fake-domain1/**'], description: 'fake-domain1' } },
341
- cwd: TEST_DIR,
342
- force: true
343
- }
344
-
345
- const result = createPathBasedPipeline(ctx)
346
- const parsedYaml = parse(result.yamlContent)
347
-
348
- // Verify workflow_call inputs are set
349
- expect(parsedYaml.on.workflow_call?.inputs?.version).toEqual({
350
- description: 'The version to deploy',
351
- required: false,
352
- type: 'string'
353
- })
354
- expect(parsedYaml.on.workflow_call?.inputs?.baseRef).toEqual({
355
- description: 'The base reference for comparison',
356
- required: false,
357
- type: 'string'
358
- })
359
- })
360
-
361
- it('should correctly apply merge operations for branch configuration', async () => {
362
- const existingPipeline = {
363
- name: "Test Pipeline",
364
- on: {
365
- pull_request: {
366
- branches: ['develop', 'feature', 'custom-branch']
367
- }
368
- },
369
- jobs: {}
370
- }
371
-
372
- const ctx = {
373
- ciProvider: 'github',
374
- mergeStrategy: 'fast-forward',
375
- requireConventionalCommits: true,
376
- initialBranch: 'alpha',
377
- finalBranch: 'epsilon',
378
- branchFlow: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
379
- semver: { bumpRules: { feat: 'minor', fix: 'patch', breaking: 'major' } },
380
- actions: { onDevelopMerge: ['runTests'], onStagingMerge: ['runTests'] },
381
- domains: { 'fake-domain1': { paths: ['apps/fake-domain1/**'], description: 'fake-domain1' } },
382
- existingPipeline,
383
- cwd: TEST_DIR,
384
- force: true
385
- }
386
-
387
- const result = createPathBasedPipeline(ctx)
388
- const parsedYaml = parse(result.yamlContent)
389
-
390
- // Verify branches are merged (user + template)
391
- const branches = parsedYaml.on.pull_request.branches
392
- expect(branches).toContain('develop')
393
- expect(branches).toContain('feature')
394
- expect(branches).toContain('custom-branch')
395
- expect(branches).toContain('alpha')
396
- expect(branches).toContain('beta')
397
- expect(branches).toContain('gamma')
398
- expect(branches).toContain('delta')
399
- expect(branches).toContain('epsilon')
400
- })
401
-
402
- it('should correctly apply overwrite operations for core Pipecraft jobs', async () => {
403
- const existingPipeline = {
404
- name: "Test Pipeline",
405
- on: { pull_request: { branches: ['develop'] } },
406
- jobs: {
407
- changes: {
408
- runs_on: 'ubuntu-latest',
409
- steps: [
410
- {
411
- name: 'Old Changes Job',
412
- run: 'echo "This should be overwritten"'
413
- }
414
- ]
415
- },
416
- version: {
417
- runs_on: 'ubuntu-latest',
418
- steps: [
419
- {
420
- name: 'Old Version Job',
421
- run: 'echo "This should be overwritten"'
422
- }
423
- ]
424
- }
425
- }
426
- }
427
-
428
- const ctx = {
429
- ciProvider: 'github',
430
- mergeStrategy: 'fast-forward',
431
- requireConventionalCommits: true,
432
- initialBranch: 'alpha',
433
- finalBranch: 'epsilon',
434
- branchFlow: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
435
- semver: { bumpRules: { feat: 'minor', fix: 'patch', breaking: 'major' } },
436
- actions: { onDevelopMerge: ['runTests'], onStagingMerge: ['runTests'] },
437
- domains: { 'fake-domain1': { paths: ['apps/fake-domain1/**'], description: 'fake-domain1' } },
438
- existingPipeline,
439
- cwd: TEST_DIR,
440
- force: true
441
- }
442
-
443
- const result = createPathBasedPipeline(ctx)
444
- const parsedYaml = parse(result.yamlContent)
445
-
446
- // Verify core jobs are overwritten with template versions
447
- expect(parsedYaml.jobs.changes.steps[0].uses).toBe('./.github/actions/detect-changes')
448
- expect(parsedYaml.jobs.version.steps[0].uses).toBe('./.github/actions/calculate-version')
449
- expect(parsedYaml.jobs.changes.steps[0].name).toBeUndefined() // No custom name
450
- expect(parsedYaml.jobs.version.steps[0].name).toBeUndefined() // No custom name
451
- })
452
-
453
- it('should correctly apply preserve operations for user-managed sections', async () => {
454
- const existingPipeline = {
455
- name: "Test Pipeline",
456
- on: { pull_request: { branches: ['develop'] } },
457
- jobs: {
458
- 'testing-section': {
459
- 'test-api': {
460
- needs: 'changes',
461
- runs_on: 'ubuntu-latest',
462
- steps: [
463
- {
464
- name: 'Test API',
465
- run: 'echo "Running API tests"'
466
- }
467
- ]
468
- }
469
- },
470
- 'deployment-section': {
471
- 'deploy-api': {
472
- needs: 'version',
473
- runs_on: 'ubuntu-latest',
474
- steps: [
475
- {
476
- name: 'Deploy API',
477
- run: 'echo "Deploying API"'
478
- }
479
- ]
480
- }
481
- }
482
- }
483
- }
484
-
485
- const ctx = {
486
- ciProvider: 'github',
487
- mergeStrategy: 'fast-forward',
488
- requireConventionalCommits: true,
489
- initialBranch: 'alpha',
490
- finalBranch: 'epsilon',
491
- branchFlow: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
492
- semver: { bumpRules: { feat: 'minor', fix: 'patch', breaking: 'major' } },
493
- actions: { onDevelopMerge: ['runTests'], onStagingMerge: ['runTests'] },
494
- domains: { 'fake-domain1': { paths: ['apps/fake-domain1/**'], description: 'fake-domain1' } },
495
- existingPipeline,
496
- cwd: TEST_DIR,
497
- force: true
498
- }
499
-
500
- const result = createPathBasedPipeline(ctx)
501
- const parsedYaml = parse(result.yamlContent)
502
-
503
- // Verify user-managed sections are preserved
504
- expect(parsedYaml.jobs['testing-section']['test-api']).toBeDefined()
505
- expect(parsedYaml.jobs['testing-section']['test-api'].steps[0].name).toBe('Test API')
506
- expect(parsedYaml.jobs['deployment-section']['deploy-api']).toBeDefined()
507
- expect(parsedYaml.jobs['deployment-section']['deploy-api'].steps[0].name).toBe('Deploy API')
508
- })
509
- })
510
- })