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
package/src/cli/index.ts DELETED
@@ -1,414 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // PipeCraft CLI - Automated CI/CD pipeline generator
4
- // Test change for deploy flow validation
5
- import { Command } from 'commander'
6
- import { cosmiconfigSync } from 'cosmiconfig'
7
- import { runModule, prompt } from '@featherscloud/pinion'
8
- import { join } from 'path'
9
- import { fileURLToPath } from 'url'
10
- import { dirname } from 'path'
11
- import { IdempotencyManager } from '../utils/idempotency.js'
12
- import { VersionManager } from '../utils/versioning.js'
13
- import { loadConfig, validateConfig } from '../utils/config.js'
14
- import { PipecraftConfig } from '../types/index.js'
15
- import { setupGitHubPermissions } from '../utils/github-setup.js'
16
- import { runPreflightChecks, formatPreflightResults, checkNodeVersion } from '../utils/preflight.js'
17
-
18
- const __filename = fileURLToPath(import.meta.url)
19
- const __dirname = dirname(__filename)
20
-
21
- const program = new Command()
22
-
23
- // Configure the CLI
24
- program
25
- .name('pipecraft')
26
- .description('CLI tool for managing trunk-based development workflows')
27
- .version('1.0.0')
28
-
29
- console.log("pipecraft edit")
30
-
31
- // Global options
32
- program
33
- .option('-c, --config <path>', 'path to config file', '.pipecraftrc.json')
34
- .option('-p, --pipeline <path>', 'path to existing pipeline file for merging', '.github/workflows/pipeline.yml')
35
- .option('-o, --output-pipeline <path>', 'path to output pipeline file (for testing)', '.github/workflows/pipeline.yml')
36
- .option('-v, --verbose', 'verbose output')
37
- .option('--force', 'force regeneration even if files unchanged')
38
- .option('--dry-run', 'show what would be done without making changes')
39
-
40
- // Init command - Initialize configuration
41
- program
42
- .command('init')
43
- .description('Initialize pipecraft configuration')
44
- .option('-f, --force', 'overwrite existing config file')
45
- .option('-i, --interactive', 'run interactive setup wizard')
46
- .option('--with-versioning', 'include version management setup')
47
- .option('--ci-provider <provider>', 'CI provider (github|gitlab)', 'github')
48
- .option('--merge-strategy <strategy>', 'merge strategy (fast-forward|merge)', 'fast-forward')
49
- .option('--initial-branch <branch>', 'initial development branch', 'develop')
50
- .option('--final-branch <branch>', 'final production branch', 'main')
51
- .action(async (options) => {
52
- try {
53
- const globalOptions = program.opts()
54
-
55
- await runModule(join(__dirname, '../generators/init.tpl.ts'), {
56
- cwd: process.cwd(),
57
- argv: process.argv,
58
- pinion: {
59
- logger: {
60
- ...console,
61
- notice: console.log
62
- },
63
- prompt: prompt as any,
64
- cwd: process.cwd(),
65
- force: options.force || globalOptions.force || false,
66
- trace: [],
67
- exec: async (command: string, args: string[]) => {
68
- const { spawn } = await import('child_process')
69
- return new Promise((resolve, reject) => {
70
- const child = spawn(command, args, { stdio: 'inherit', shell: true })
71
- child.once('exit', (code: number) => (code === 0 ? resolve(code) : reject(code)))
72
- })
73
- }
74
- }
75
- })
76
-
77
- // Setup version management if requested
78
- if (options.withVersioning) {
79
- const config = loadConfig(globalOptions.config)
80
- const versionManager = new VersionManager(config)
81
- versionManager.setupVersionManagement()
82
- console.log('✅ Version management setup completed!')
83
- }
84
-
85
- console.log('✅ Configuration initialized successfully!')
86
- } catch (error: any) {
87
- console.error('❌ Failed to initialize configuration:', error.message)
88
- process.exit(1)
89
- }
90
- })
91
-
92
- // Generate command - Generate workflow files
93
- program
94
- .command('generate')
95
- .description('Generate CI/CD workflows from configuration')
96
- .option('-o, --output <path>', 'output directory for generated workflows', '.github/workflows')
97
- .option('--skip-unchanged', 'skip files that haven\'t changed')
98
- .option('--skip-checks', 'skip pre-flight checks (not recommended)')
99
- .action(async (options) => {
100
- try {
101
- const globalOptions = program.opts()
102
- const configPath = globalOptions.config
103
- const pipelinePath = globalOptions.pipeline
104
- const outputPipelinePath = globalOptions.outputPipeline
105
-
106
- // Run pre-flight checks unless skipped
107
- if (!options.skipChecks) {
108
- console.log('🔍 Running pre-flight checks...\n')
109
-
110
- const checks = runPreflightChecks()
111
- const { allPassed, output, nextSteps } = formatPreflightResults(checks)
112
-
113
- console.log(output)
114
- console.log()
115
-
116
- if (!allPassed) {
117
- console.error('❌ Pre-flight checks failed. Fix the issues above and try again.')
118
- console.error(' Or use --skip-checks to bypass (not recommended)\n')
119
- process.exit(1)
120
- }
121
-
122
- console.log('✅ All pre-flight checks passed!')
123
-
124
- // Store next steps for later display (after successful generation)
125
- if (nextSteps) {
126
- (options as any)._nextSteps = nextSteps
127
- }
128
-
129
- console.log()
130
- }
131
-
132
- if (globalOptions.verbose) {
133
- console.log(`📖 Reading config from: ${configPath}`)
134
- console.log(`📖 Reading pipeline from: ${pipelinePath}`)
135
- }
136
-
137
- // Load configuration
138
- const config = loadConfig(configPath) as PipecraftConfig
139
-
140
- // Check idempotency if not forcing
141
- if (!globalOptions.force && !globalOptions.dryRun) {
142
- const idempotencyManager = new IdempotencyManager(config)
143
-
144
- if (!(await idempotencyManager.hasChanges())) {
145
- console.log('ℹ️ No changes detected. Use --force to regenerate anyway.')
146
- return
147
- }
148
-
149
- if (globalOptions.verbose) {
150
- console.log('🔄 Changes detected, regenerating workflows...')
151
- }
152
- }
153
-
154
- if (globalOptions.dryRun) {
155
- console.log('🔍 Dry run mode - would generate workflows')
156
- return
157
- }
158
-
159
- await runModule(join(__dirname, '../generators/workflows.tpl.js'), {
160
- cwd: process.cwd(),
161
- argv: process.argv,
162
- pipelinePath: pipelinePath,
163
- outputPipelinePath: outputPipelinePath,
164
- config: config,
165
- pinion: {
166
- logger: {
167
- ...console,
168
- notice: console.log
169
- },
170
- prompt: prompt as any,
171
- cwd: process.cwd(),
172
- force: globalOptions.force || false,
173
- trace: [],
174
- exec: async (command: string, args: string[]) => {
175
- const { spawn } = await import('child_process')
176
- return new Promise((resolve, reject) => {
177
- const child = spawn(command, args, { stdio: 'inherit', shell: true })
178
- child.once('exit', (code: number) => (code === 0 ? resolve(code) : reject(code)))
179
- })
180
- }
181
- }
182
- } as any)
183
-
184
- // Update idempotency cache
185
- const idempotencyManager = new IdempotencyManager(config)
186
- await idempotencyManager.updateCache()
187
-
188
- console.log(`✅ Generated workflows in: ${options.output}`)
189
-
190
- // Display next steps if available
191
- if ((options as any)._nextSteps) {
192
- console.log()
193
- const steps = (options as any)._nextSteps as string[]
194
- steps.forEach((step: string) => console.log(step))
195
- }
196
- } catch (error: any) {
197
- console.error('❌ Failed to generate workflows:', error.message)
198
- process.exit(1)
199
- }
200
- })
201
-
202
- // Validate command - Validate configuration
203
- program
204
- .command('validate')
205
- .description('Validate configuration file')
206
- .action(async (options) => {
207
- try {
208
- const globalOptions = program.opts()
209
- const configPath = globalOptions.config
210
-
211
- const config = loadConfig(configPath)
212
- validateConfig(config)
213
-
214
- console.log('✅ Configuration is valid!')
215
- } catch (error: any) {
216
- console.error('❌ Configuration validation failed:', error.message)
217
- process.exit(1)
218
- }
219
- })
220
-
221
- // Verify command - Check if setup is correct
222
- program
223
- .command('verify')
224
- .description('Verify that pipecraft is properly set up')
225
- .action(async () => {
226
- try {
227
- const explorer = cosmiconfigSync('trunkflow')
228
- const result = explorer.search()
229
-
230
- if (!result) {
231
- console.log('⚠️ No configuration file found. Run "pipecraft init" to get started.')
232
- process.exit(1)
233
- }
234
-
235
- console.log(`✅ Found configuration at: ${result.filepath}`)
236
-
237
- const config = result.config
238
- validateConfig(config)
239
- console.log('✅ Configuration is valid!')
240
-
241
- // Check if workflows exist
242
- const fs = await import('fs')
243
- const path = await import('path')
244
-
245
- if (config.ciProvider === 'github') {
246
- const workflowPath = path.join(process.cwd(), '.github/workflows/pipeline.yml')
247
- if (fs.existsSync(workflowPath)) {
248
- console.log('✅ GitHub Actions workflows exist!')
249
- } else {
250
- console.log('⚠️ GitHub Actions workflows not found. Run "pipecraft generate" to create them.')
251
- }
252
- }
253
-
254
- } catch (error: any) {
255
- console.error('❌ Verification failed:', error.message)
256
- process.exit(1)
257
- }
258
- })
259
-
260
- // Version command - Version management
261
- program
262
- .command('version')
263
- .description('Version management commands')
264
- .option('--check', 'check current version and next version')
265
- .option('--bump', 'bump version using conventional commits')
266
- .option('--release', 'create release with version bump')
267
- .action(async (options) => {
268
- try {
269
- const globalOptions = program.opts()
270
- const config = loadConfig(globalOptions.config) as PipecraftConfig
271
- const versionManager = new VersionManager(config)
272
-
273
- if (options.check) {
274
- const currentVersion = versionManager.getCurrentVersion()
275
- const nextVersion = versionManager.calculateNextVersion()
276
-
277
- console.log(`📦 Current version: ${currentVersion}`)
278
- console.log(`📦 Next version: ${nextVersion.version} (${nextVersion.type})`)
279
-
280
- // Check conventional commits
281
- const isValid = versionManager.validateConventionalCommits()
282
- console.log(`📝 Conventional commits: ${isValid ? '✅ Valid' : '❌ Invalid'}`)
283
- }
284
-
285
- if (options.bump) {
286
- console.log('🔄 Bumping version...')
287
- // This would run release-it in dry-run mode first
288
- console.log('✅ Version bump completed!')
289
- }
290
-
291
- if (options.release) {
292
- console.log('🚀 Creating release...')
293
- // This would run the actual release process
294
- console.log('✅ Release created!')
295
- }
296
-
297
- } catch (error: any) {
298
- console.error('❌ Version command failed:', error.message)
299
- process.exit(1)
300
- }
301
- })
302
-
303
- // Setup command - Create necessary branches
304
- program
305
- .command('setup')
306
- .description('Set up the repository with necessary branches from branch flow')
307
- .option('--force', 'Force creation even if branches exist')
308
- .action(async (options) => {
309
- try {
310
- const globalOptions = program.opts()
311
- const configPath = globalOptions.config
312
-
313
- if (globalOptions.verbose) {
314
- console.log(`📖 Reading config from: ${configPath}`)
315
- }
316
-
317
- // Load configuration
318
- const config = loadConfig(configPath) as PipecraftConfig
319
-
320
- if (!config.branchFlow || config.branchFlow.length === 0) {
321
- console.log('⚠️ No branch flow configured in config file')
322
- return
323
- }
324
-
325
- console.log(`🌿 Setting up branches: ${config.branchFlow.join(' → ')}`)
326
-
327
- // Check current branch
328
- const { execSync } = await import('child_process')
329
- const currentBranch = execSync('git branch --show-current', { encoding: 'utf8' }).trim()
330
- console.log(`📍 Current branch: ${currentBranch}`)
331
-
332
- // Check which branches exist
333
- const existingBranches = execSync('git branch -a', { encoding: 'utf8' })
334
- .split('\n')
335
- .map(line => line.trim().replace('* ', '').replace('remotes/origin/', ''))
336
- .filter(line => line.length > 0)
337
-
338
- console.log(`📋 Existing branches: ${existingBranches.join(', ')}`)
339
-
340
- // Create missing branches
341
- for (const branch of config.branchFlow) {
342
- if (existingBranches.includes(branch)) {
343
- console.log(`✅ Branch '${branch}' already exists locally`)
344
- } else {
345
- console.log(`🌱 Creating branch '${branch}'...`)
346
- try {
347
- execSync(`git checkout -b ${branch}`, { stdio: 'inherit' })
348
- console.log(`✅ Created branch '${branch}'`)
349
- } catch (error: any) {
350
- if (error.message.includes('already exists')) {
351
- console.log(`ℹ️ Branch '${branch}' already exists (checked out from remote)`)
352
- } else {
353
- throw error
354
- }
355
- }
356
- }
357
-
358
- // Push branch to remote if it doesn't exist there
359
- try {
360
- console.log(`📤 Checking if '${branch}' exists on remote...`)
361
- execSync(`git ls-remote --heads origin ${branch}`, { stdio: 'pipe' })
362
- console.log(`✅ Branch '${branch}' already exists on remote`)
363
- } catch (error: any) {
364
- console.log(`🚀 Pushing branch '${branch}' to remote...`)
365
- execSync(`git push -u origin ${branch}`, { stdio: 'inherit' })
366
- console.log(`✅ Pushed branch '${branch}' to remote`)
367
- }
368
- }
369
-
370
- // Return to original branch
371
- execSync(`git checkout ${currentBranch}`, { stdio: 'inherit' })
372
- console.log(`🔄 Returned to original branch: ${currentBranch}`)
373
-
374
- console.log('✅ Branch setup complete!')
375
-
376
- } catch (error: any) {
377
- console.error('❌ Setup command failed:', error.message)
378
- process.exit(1)
379
- }
380
- })
381
-
382
- // Setup GitHub command - Configure GitHub Actions permissions
383
- program
384
- .command('setup-github')
385
- .description('Configure GitHub Actions workflow permissions for PipeCraft')
386
- .option('--apply', 'Automatically apply changes without prompting')
387
- .option('--force', 'Alias for --apply')
388
- .action(async (options) => {
389
- try {
390
- const autoApply = options.apply || options.force
391
- await setupGitHubPermissions(autoApply)
392
- } catch (error: any) {
393
- console.error('❌ GitHub setup failed:', error.message)
394
- if (error.stack) {
395
- console.error(error.stack)
396
- }
397
- process.exit(1)
398
- }
399
- })
400
-
401
- // Parse command line arguments
402
- program.parse()
403
-
404
- // Show help if no command provided
405
- if (!process.argv.slice(2).length) {
406
- program.outputHelp()
407
- }
408
- // Test comment for deploy job validation
409
- // Final test for deploy-core job
410
- // Test commit to trigger deploy-core job - Wed Oct 15 13:47:31 EDT 2025
411
- // Test commit to trigger deploy-core job - Wed Oct 15 13:51:31 EDT 2025
412
-
413
- // test commit # on Wed Oct 15 14:07:07 EDT 2025
414
- // test commit # on Wed Oct 15 15:12:47 EDT 2025
@@ -1,126 +0,0 @@
1
- import { PinionContext, toFile, renderTemplate, prompt, when, writeJSON } from '@featherscloud/pinion'
2
- import { existsSync } from 'fs'
3
- import { IdempotencyManager } from '../utils/idempotency.js'
4
- import { VersionManager } from '../utils/versioning.js'
5
- import { PipecraftConfig } from '../types/index.js'
6
-
7
- const defaultConfig = {
8
- ciProvider: 'github' as const,
9
- mergeStrategy: 'fast-forward' as const,
10
- requireConventionalCommits: true,
11
- initialBranch: 'develop',
12
- finalBranch: 'main',
13
- branchFlow: ['develop', 'staging', 'main'],
14
- semver: {
15
- bumpRules: {
16
- feat: 'minor',
17
- fix: 'patch',
18
- breaking: 'major'
19
- }
20
- },
21
- actions: {
22
- onDevelopMerge: ['runTests', 'fastForwardToStaging'],
23
- onStagingMerge: ['runTests', 'calculateVersion', 'createOrFastForwardToMain']
24
- },
25
- domains: {
26
- api: {
27
- paths: ['apps/api/**'],
28
- description: 'API application changes'
29
- },
30
- web: {
31
- paths: ['apps/web/**'],
32
- description: 'Web application changes'
33
- },
34
- libs: {
35
- paths: ['libs/**'],
36
- description: 'Shared library changes'
37
- },
38
- cicd: {
39
- paths: ['.github/workflows/**'],
40
- description: 'CI/CD configuration changes'
41
- }
42
- }
43
- }
44
-
45
- const configTemplate = (ctx: PipecraftConfig) => {
46
- const config = {
47
- ciProvider: ctx.ciProvider,
48
- mergeStrategy: ctx.mergeStrategy,
49
- requireConventionalCommits: ctx.requireConventionalCommits,
50
- initialBranch: ctx.initialBranch,
51
- finalBranch: ctx.finalBranch,
52
- branchFlow: ctx.branchFlow,
53
- semver: {
54
- bumpRules: ctx.semver.bumpRules
55
- },
56
- actions: {
57
- onDevelopMerge: ctx.actions.onDevelopMerge,
58
- onStagingMerge: ctx.actions.onStagingMerge
59
- },
60
- domains: ctx.domains
61
- }
62
-
63
- return JSON.stringify(config, null, 2)
64
- }
65
-
66
-
67
- export const generate = (ctx: PinionContext) =>
68
- Promise.resolve(ctx)
69
- .then(prompt([
70
- {
71
- type: 'input',
72
- name: 'projectName',
73
- message: 'What is your project name?',
74
- default: 'my-project'
75
- },
76
- {
77
- type: 'list',
78
- name: 'ciProvider',
79
- message: 'Which CI provider are you using?',
80
- choices: [
81
- { name: 'GitHub Actions', value: 'github' },
82
- { name: 'GitLab CI/CD', value: 'gitlab' }
83
- ],
84
- default: 'github'
85
- },
86
- {
87
- type: 'list',
88
- name: 'mergeStrategy',
89
- message: 'What merge strategy do you prefer?',
90
- choices: [
91
- { name: 'Fast-forward only (recommended)', value: 'fast-forward' },
92
- { name: 'Merge commits', value: 'merge' }
93
- ],
94
- default: 'fast-forward'
95
- },
96
- {
97
- type: 'confirm',
98
- name: 'requireConventionalCommits',
99
- message: 'Require conventional commit format for PR titles?',
100
- default: true
101
- },
102
- {
103
- type: 'input',
104
- name: 'initialBranch',
105
- message: 'What is your development branch name?',
106
- default: 'develop'
107
- },
108
- {
109
- type: 'input',
110
- name: 'finalBranch',
111
- message: 'What is your production branch name?',
112
- default: 'main'
113
- },
114
- {
115
- type: 'input',
116
- name: 'branchFlow',
117
- message: 'Enter your branch flow (comma-separated)',
118
- default: 'develop,staging,main',
119
- filter: (input: string) => input.split(',').map(b => b.trim())
120
- }
121
- ]))
122
- .then((ctx) => ({ ...ctx, ...defaultConfig } as PipecraftConfig))
123
- .then((config) => {
124
- const content = configTemplate(config)
125
- return writeJSON(() => content, toFile('.pipecraftrc.json'))(ctx)
126
- })
@@ -1,80 +0,0 @@
1
- import { PinionContext, toFile, renderTemplate, loadJSON, when } from '@featherscloud/pinion'
2
- import { IdempotencyManager } from '../utils/idempotency.js'
3
- import { PipecraftConfig } from '../types/index.js'
4
- import { readFileSync, existsSync } from 'fs'
5
- import { parse } from 'yaml'
6
-
7
- // Import individual workflow templates
8
- import { generate as generateTagWorkflow } from '../templates/actions/create-tag.yml.tpl.js'
9
- import { generate as generateChangesWorkflow } from '../templates/actions/detect-changes.yml.tpl.js'
10
- import { generate as generateVersionWorkflow } from '../templates/actions/calculate-version.yml.tpl.js'
11
- import { generate as generateCreatePRWorkflow } from '../templates/actions/create-pr.yml.tpl.js'
12
- import { generate as generateBranchWorkflow } from '../templates/actions/manage-branch.yml.tpl.js'
13
- import { generate as generatePromoteBranchWorkflow } from '../templates/actions/promote-branch.yml.tpl.js'
14
- import { generate as generatePathBasedPipeline } from '../templates/workflows/pipeline-path-based.yml.tpl.js'
15
-
16
- const defaultConfig = {
17
- ciProvider: 'github' as const,
18
- mergeStrategy: 'fast-forward' as const,
19
- requireConventionalCommits: true,
20
- initialBranch: 'develop',
21
- finalBranch: 'main',
22
- branchFlow: ['develop', 'staging', 'main'],
23
- semver: {
24
- bumpRules: {
25
- feat: 'minor',
26
- fix: 'patch',
27
- breaking: 'major'
28
- }
29
- },
30
- actions: {
31
- onDevelopMerge: ['runTests', 'fastForwardToStaging'],
32
- onStagingMerge: ['runTests', 'calculateVersion', 'createOrFastForwardToMain']
33
- },
34
- domains: {
35
- api: { paths: ['apps/api/**'], description: 'API application changes' },
36
- web: { paths: ['apps/web/**'], description: 'Web application changes' },
37
- libs: { paths: ['libs/**'], description: 'Shared library changes' },
38
- cicd: { paths: ['.github/workflows/**'], description: 'CI/CD configuration changes' }
39
- }
40
- }
41
-
42
- export const generate = (ctx: PinionContext & { pipelinePath?: string, outputPipelinePath?: string, config?: any }) =>
43
- Promise.resolve(ctx)
44
- .then((ctx) => {
45
- console.log('🔧 Generating GitHub Actions...')
46
-
47
- // Load existing pipeline if provided
48
- let existingPipeline = null
49
- let existingPipelineContent = null
50
- if (ctx.pipelinePath && existsSync(ctx.pipelinePath)) {
51
- try {
52
- existingPipelineContent = readFileSync(ctx.pipelinePath, 'utf8')
53
- existingPipeline = parse(existingPipelineContent)
54
- console.log(`📖 Loaded existing pipeline from: ${ctx.pipelinePath}`)
55
- } catch (error) {
56
- console.warn(`⚠️ Failed to load existing pipeline: ${error}`)
57
- }
58
- }
59
-
60
- return { ...ctx, ...defaultConfig, ...ctx.config, ...ctx, existingPipeline, existingPipelineContent, outputPipelinePath: ctx.outputPipelinePath }
61
- })
62
- .then((ctx) => {
63
- // Generate individual GitHub Actions
64
- return Promise.all([
65
- generateChangesWorkflow(ctx),
66
- generateTagWorkflow(ctx),
67
- generateVersionWorkflow(ctx),
68
- generateCreatePRWorkflow(ctx),
69
- generateBranchWorkflow(ctx),
70
- generatePromoteBranchWorkflow(ctx)
71
- ]).then(() => ctx)
72
- })
73
- .then((ctx) => {
74
- // Generate the main pipeline
75
- return generatePathBasedPipeline(ctx)
76
- })
77
- .then((ctx) => {
78
- console.log('✅ Generated workflows in: .github/workflows')
79
- return ctx
80
- })