pipecraft 0.28.2 → 0.29.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 (62) hide show
  1. package/README.md +5 -2
  2. package/dist/cli/index.js +1 -9
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/generators/init.tpl.d.ts.map +1 -1
  5. package/dist/generators/init.tpl.js +140 -67
  6. package/dist/generators/init.tpl.js.map +1 -1
  7. package/dist/generators/workflows.tpl.d.ts.map +1 -1
  8. package/dist/generators/workflows.tpl.js +18 -5
  9. package/dist/generators/workflows.tpl.js.map +1 -1
  10. package/dist/templates/actions/detect-changes-nx.yml.tpl.d.ts +32 -0
  11. package/dist/templates/actions/detect-changes-nx.yml.tpl.d.ts.map +1 -0
  12. package/dist/templates/actions/detect-changes-nx.yml.tpl.js +227 -0
  13. package/dist/templates/actions/detect-changes-nx.yml.tpl.js.map +1 -0
  14. package/dist/templates/workflows/pipeline-nx.yml.tpl.d.ts +22 -0
  15. package/dist/templates/workflows/pipeline-nx.yml.tpl.d.ts.map +1 -0
  16. package/dist/templates/workflows/pipeline-nx.yml.tpl.js +196 -0
  17. package/dist/templates/workflows/pipeline-nx.yml.tpl.js.map +1 -0
  18. package/dist/templates/workflows/pipeline.yml.tpl.d.ts +22 -0
  19. package/dist/templates/workflows/pipeline.yml.tpl.d.ts.map +1 -0
  20. package/dist/templates/workflows/pipeline.yml.tpl.js +136 -0
  21. package/dist/templates/workflows/pipeline.yml.tpl.js.map +1 -0
  22. package/dist/templates/workflows/shared/index.d.ts +11 -0
  23. package/dist/templates/workflows/shared/index.d.ts.map +1 -0
  24. package/dist/templates/workflows/shared/index.js +11 -0
  25. package/dist/templates/workflows/shared/index.js.map +1 -0
  26. package/dist/templates/workflows/shared/operations-changes.d.ts +17 -0
  27. package/dist/templates/workflows/shared/operations-changes.d.ts.map +1 -0
  28. package/dist/templates/workflows/shared/operations-changes.js +49 -0
  29. package/dist/templates/workflows/shared/operations-changes.js.map +1 -0
  30. package/dist/templates/workflows/shared/operations-domain-jobs.d.ts +31 -0
  31. package/dist/templates/workflows/shared/operations-domain-jobs.d.ts.map +1 -0
  32. package/dist/templates/workflows/shared/operations-domain-jobs.js +139 -0
  33. package/dist/templates/workflows/shared/operations-domain-jobs.js.map +1 -0
  34. package/dist/templates/workflows/shared/operations-header.d.ts +15 -0
  35. package/dist/templates/workflows/shared/operations-header.d.ts.map +1 -0
  36. package/dist/templates/workflows/shared/operations-header.js +158 -0
  37. package/dist/templates/workflows/shared/operations-header.js.map +1 -0
  38. package/dist/templates/workflows/shared/operations-tag-promote.d.ts +16 -0
  39. package/dist/templates/workflows/shared/operations-tag-promote.d.ts.map +1 -0
  40. package/dist/templates/workflows/shared/operations-tag-promote.js +115 -0
  41. package/dist/templates/workflows/shared/operations-tag-promote.js.map +1 -0
  42. package/dist/templates/workflows/shared/operations-version.d.ts +16 -0
  43. package/dist/templates/workflows/shared/operations-version.d.ts.map +1 -0
  44. package/dist/templates/workflows/shared/operations-version.js +57 -0
  45. package/dist/templates/workflows/shared/operations-version.js.map +1 -0
  46. package/dist/templates/yaml-format-utils.d.ts +24 -0
  47. package/dist/templates/yaml-format-utils.d.ts.map +1 -0
  48. package/dist/templates/yaml-format-utils.js +50 -0
  49. package/dist/templates/yaml-format-utils.js.map +1 -0
  50. package/dist/types/index.d.ts +53 -0
  51. package/dist/types/index.d.ts.map +1 -1
  52. package/package.json +3 -1
  53. package/src/generators/init.tpl.ts +151 -73
  54. package/src/generators/workflows.tpl.ts +19 -5
  55. package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts +0 -129
  56. package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts.map +0 -1
  57. package/dist/templates/workflows/pipeline-path-based.yml.tpl.js +0 -1057
  58. package/dist/templates/workflows/pipeline-path-based.yml.tpl.js.map +0 -1
  59. package/dist/utils/github-setup-v2.d.ts +0 -15
  60. package/dist/utils/github-setup-v2.d.ts.map +0 -1
  61. package/dist/utils/github-setup-v2.js +0 -217
  62. package/dist/utils/github-setup-v2.js.map +0 -1
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Detect Changes Nx Action Template
3
+ *
4
+ * Generates a GitHub composite action that detects which domains have changed
5
+ * using Nx dependency graph analysis with path-based fallback.
6
+ *
7
+ * ## Purpose
8
+ *
9
+ * For Nx monorepos, this action uses `nx show projects --affected` to leverage
10
+ * the dependency graph for intelligent change detection. It maps affected Nx
11
+ * projects to configured domains and falls back to path-based detection when
12
+ * Nx is unavailable.
13
+ *
14
+ * ## Generated Action Location
15
+ *
16
+ * `.github/actions/detect-changes-nx/action.yml`
17
+ *
18
+ * @module templates/actions/detect-changes-nx.yml.tpl
19
+ */
20
+ import { toFile, renderTemplate } from '@featherscloud/pinion';
21
+ import fs from 'fs';
22
+ import { logger } from '../../utils/logger.js';
23
+ /**
24
+ * Generates the detect-changes-nx composite action YAML content.
25
+ *
26
+ * Creates a GitHub Actions composite action that:
27
+ * - Checks for Nx availability in the repository
28
+ * - Uses `nx show projects --affected` for dependency graph analysis
29
+ * - Maps affected projects to domains
30
+ * - Falls back to path-based detection if Nx isn't available
31
+ * - Outputs Nx-specific information (affected projects, Nx availability)
32
+ *
33
+ * @param {any} ctx - Context containing domains configuration
34
+ * @param {Record<string, DomainConfig>} ctx.domains - Domain configurations with path patterns
35
+ * @returns {string} YAML content for the composite action
36
+ */
37
+ const changesNxActionTemplate = (ctx) => {
38
+ const domainOutputs = Object.entries(ctx.domains).map((entry) => {
39
+ const [domainName, domainConfig] = entry;
40
+ return ` ${domainName}:
41
+ description: 'Whether ${domainName} domain has changes'
42
+ value: \${{ steps.merge.outputs.${domainName} }}`;
43
+ }).join('\n');
44
+ const domainFilters = Object.entries(ctx.domains).map((entry) => {
45
+ const [domainName, domainConfig] = entry;
46
+ return ` ${domainName}:\n - '${domainConfig.paths.join("'\\n - '")}'`;
47
+ }).join('\n');
48
+ // Generate Nx pattern matching logic for each domain
49
+ const domainNames = Object.keys(ctx.domains);
50
+ const nxPatternMatching = domainNames.map(domainName => {
51
+ return ` # Check ${domainName} domain patterns
52
+ if echo "$project" | grep -qE "(${domainName}|$(echo "${domainName}" | sed 's/-/[-_]/g'))"; then
53
+ ${domainName.toUpperCase()}_AFFECTED=true
54
+ echo " ✅ $project matches ${domainName} domain"
55
+ fi`;
56
+ }).join('\n');
57
+ const nxFlagInit = domainNames.map(domainName => ` ${domainName.toUpperCase()}_AFFECTED=false`).join('\n');
58
+ const nxOutputs = domainNames.map(domainName => ` echo "${domainName}=$${domainName.toUpperCase()}_AFFECTED" >> $GITHUB_OUTPUT`).join('\n');
59
+ const nxFallbackOutputs = domainNames.map(domainName => ` echo "${domainName}=false" >> $GITHUB_OUTPUT`).join('\n');
60
+ const pathFilterOutputs = domainNames.map(domainName => ` echo "${domainName}=\${{ contains(steps.filter.outputs.changes, '${domainName}') }}" >> $GITHUB_OUTPUT`).join('\n');
61
+ const nxMergeOutputs = domainNames.map(domainName => ` echo "${domainName}=\${{ steps.nx-filter.outputs.${domainName} }}" >> $GITHUB_OUTPUT`).join('\n');
62
+ const resultEchoes = domainNames.map(domainName => ` echo " ${domainName}: \${{ steps.merge.outputs.${domainName} }}"`).join('\n');
63
+ // Generate the composite action YAML
64
+ return `name: 'Detect Changes with Nx Support'
65
+ description: 'Enhanced change detection using Nx dependency graph with path-based fallback'
66
+ author: 'Pipecraft'
67
+
68
+ inputs:
69
+ baseRef:
70
+ description: 'Base reference to compare against'
71
+ required: false
72
+ default: 'main'
73
+ useNx:
74
+ description: 'Whether to use Nx dependency graph for change detection'
75
+ required: false
76
+ default: 'true'
77
+
78
+ outputs:
79
+ ${domainOutputs}
80
+ nxAvailable:
81
+ description: 'Whether Nx is available in the repository'
82
+ value: \${{ steps.nx-check.outputs.available }}
83
+ affectedProjects:
84
+ description: 'Comma-separated list of affected Nx projects'
85
+ value: \${{ steps.nx-filter.outputs.affectedProjects }}
86
+
87
+ runs:
88
+ using: 'composite'
89
+ steps:
90
+ - name: Checkout Code
91
+ uses: actions/checkout@v4
92
+ with:
93
+ fetch-depth: 0
94
+
95
+ - name: Set Base Branch
96
+ id: set-base
97
+ shell: bash
98
+ run: |
99
+ base_branch=\${{ inputs.baseRef || 'main' }}
100
+ echo "base_branch=$base_branch" >> $GITHUB_OUTPUT
101
+ echo "base_branch=$base_branch" >> $GITHUB_ENV
102
+
103
+ - name: Check for Nx
104
+ id: nx-check
105
+ shell: bash
106
+ run: |
107
+ if [ -f "nx.json" ] || ([ -f "package.json" ] && grep -q '"nx"' package.json); then
108
+ echo "available=true" >> $GITHUB_OUTPUT
109
+ echo "🔍 Nx detected in repository"
110
+ else
111
+ echo "available=false" >> $GITHUB_OUTPUT
112
+ echo "⚠️ Nx not detected, falling back to path-based detection"
113
+ fi
114
+
115
+ - name: Setup Node.js
116
+ if: steps.nx-check.outputs.available == 'true' && inputs.useNx == 'true'
117
+ uses: actions/setup-node@v4
118
+ with:
119
+ node-version: '20'
120
+
121
+ - name: Install Dependencies
122
+ if: steps.nx-check.outputs.available == 'true' && inputs.useNx == 'true'
123
+ shell: bash
124
+ run: |
125
+ echo "📦 Installing dependencies for Nx..."
126
+ if [ -f "pnpm-lock.yaml" ]; then
127
+ corepack enable
128
+ pnpm install --frozen-lockfile || pnpm install
129
+ elif [ -f "yarn.lock" ]; then
130
+ yarn install --frozen-lockfile || yarn install
131
+ elif [ -f "package-lock.json" ]; then
132
+ npm ci || npm install
133
+ else
134
+ npm install
135
+ fi
136
+
137
+ - name: Detect Changes with Nx (if available)
138
+ id: nx-filter
139
+ if: steps.nx-check.outputs.available == 'true' && inputs.useNx == 'true'
140
+ shell: bash
141
+ run: |
142
+ echo "🚀 Using Nx dependency graph for change detection"
143
+
144
+ # Get affected projects using Nx
145
+ if command -v npx >/dev/null 2>&1; then
146
+ # Get list of affected projects (newline-separated)
147
+ AFFECTED_PROJECTS_RAW=$(npx nx show projects --affected --base=\${{ steps.set-base.outputs.base_branch }} 2>/dev/null || echo "")
148
+
149
+ # Convert newlines to commas for storage
150
+ AFFECTED_PROJECTS=$(echo "$AFFECTED_PROJECTS_RAW" | tr '\\n' ',' | sed 's/,$//')
151
+ echo "affectedProjects=$AFFECTED_PROJECTS" >> $GITHUB_OUTPUT
152
+
153
+ if [ -n "$AFFECTED_PROJECTS" ]; then
154
+ echo "📦 Affected Nx projects: $AFFECTED_PROJECTS"
155
+
156
+ # Initialize domain flags
157
+ ${nxFlagInit}
158
+
159
+ # Check each affected project against domain patterns (comma-separated)
160
+ IFS=',' read -ra PROJECTS <<< "$AFFECTED_PROJECTS"
161
+ for project in "\${PROJECTS[@]}"; do
162
+ project=$(echo "$project" | xargs) # trim whitespace
163
+ ${nxPatternMatching}
164
+ done
165
+
166
+ # Set outputs
167
+ ${nxOutputs}
168
+
169
+ else
170
+ echo "No affected projects detected"
171
+ ${nxFallbackOutputs}
172
+ fi
173
+ else
174
+ echo "⚠️ npx not available, falling back to path-based detection"
175
+ ${nxFallbackOutputs}
176
+ echo "affectedProjects=" >> $GITHUB_OUTPUT
177
+ fi
178
+
179
+ - name: Detect Changes with Paths Filter (fallback)
180
+ uses: dorny/paths-filter@v3
181
+ id: filter
182
+ if: steps.nx-check.outputs.available != 'true' || inputs.useNx != 'true'
183
+ with:
184
+ base: \${{ steps.set-base.outputs.base_branch }}
185
+ filters: |
186
+ ${domainFilters}
187
+
188
+ - name: Merge filter outputs
189
+ id: merge
190
+ shell: bash
191
+ run: |
192
+ # Use Nx results if available, otherwise use path filter results
193
+ if [ "\${{ steps.nx-check.outputs.available }}" == "true" ] && [ "\${{ inputs.useNx }}" == "true" ]; then
194
+ ${nxMergeOutputs}
195
+ echo "🔍 Using Nx dependency analysis results"
196
+ echo "📦 Affected projects: \${{ steps.nx-filter.outputs.affectedProjects }}"
197
+ else
198
+ ${pathFilterOutputs}
199
+ echo "📁 Using path-based change detection"
200
+ fi
201
+
202
+ echo "📋 Change Detection Results:"
203
+ ${resultEchoes}
204
+ echo " nx-available: \${{ steps.nx-check.outputs.available }}"
205
+ `;
206
+ };
207
+ /**
208
+ * Generator entry point for detect-changes-nx composite action.
209
+ *
210
+ * Generates the `.github/actions/detect-changes-nx/action.yml` file with Nx-aware
211
+ * change detection logic. This action is used by Nx-enabled pipelines.
212
+ *
213
+ * @param {PinionContext} ctx - Pinion generator context
214
+ * @param {Record<string, DomainConfig>} ctx.domains - Domain configurations
215
+ * @returns {Promise<PinionContext>} Updated context after file generation
216
+ */
217
+ export const generate = (ctx) => Promise.resolve(ctx)
218
+ .then((ctx) => {
219
+ // Check if file exists to determine merge status
220
+ const filePath = '.github/actions/detect-changes-nx/action.yml';
221
+ const exists = fs.existsSync(filePath);
222
+ const status = exists ? '🔄 Merged with existing' : '📝 Created new';
223
+ logger.verbose(`${status} ${filePath}`);
224
+ return ctx;
225
+ })
226
+ .then(renderTemplate(changesNxActionTemplate, toFile('.github/actions/detect-changes-nx/action.yml')));
227
+ //# sourceMappingURL=detect-changes-nx.yml.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-changes-nx.yml.tpl.js","sourceRoot":"","sources":["../../../src/templates/actions/detect-changes-nx.yml.tpl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Nx Pipeline Template
3
+ *
4
+ * Generates an Nx-optimized workflow that uses `nx affected` to intelligently test
5
+ * only changed projects. Runs all Nx tasks sequentially in a single job, leveraging
6
+ * Nx's built-in caching and parallel execution.
7
+ *
8
+ * This is Option 1 (Sequential Strategy) - simple, fast, and leverages Nx's intelligence.
9
+ */
10
+ import { PinionContext } from '@featherscloud/pinion';
11
+ import { PipecraftConfig } from '../../types/index.js';
12
+ interface NxPipelineContext extends PinionContext {
13
+ config: PipecraftConfig;
14
+ branchFlow: string[];
15
+ outputPipelinePath?: string;
16
+ }
17
+ /**
18
+ * Main generator that handles merging with existing workflow
19
+ */
20
+ export declare const generate: (ctx: NxPipelineContext) => Promise<any>;
21
+ export {};
22
+ //# sourceMappingURL=pipeline-nx.yml.tpl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-nx.yml.tpl.d.ts","sourceRoot":"","sources":["../../../src/templates/workflows/pipeline-nx.yml.tpl.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAA0B,MAAM,uBAAuB,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAiBtD,UAAU,iBAAkB,SAAQ,aAAa;IAC/C,MAAM,EAAE,eAAe,CAAA;IACvB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAqFD;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,iBAAiB,iBAwH2F,CAAA"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Nx Pipeline Template
3
+ *
4
+ * Generates an Nx-optimized workflow that uses `nx affected` to intelligently test
5
+ * only changed projects. Runs all Nx tasks sequentially in a single job, leveraging
6
+ * Nx's built-in caching and parallel execution.
7
+ *
8
+ * This is Option 1 (Sequential Strategy) - simple, fast, and leverages Nx's intelligence.
9
+ */
10
+ import { renderTemplate, toFile } from '@featherscloud/pinion';
11
+ import { parseDocument, stringify } from 'yaml';
12
+ import fs from 'fs';
13
+ import { logger } from '../../utils/logger.js';
14
+ import { applyPathOperations, createValueFromString } from '../../utils/ast-path-operations.js';
15
+ import { createHeaderOperations, createChangesJobOperation, createDomainTestJobOperations, createDomainDeployJobOperations, createDomainRemoteTestJobOperations, createVersionJobOperation, createTagPromoteReleaseOperations, getDomainJobNames } from './shared/index.js';
16
+ import { formatIfConditions } from '../yaml-format-utils.js';
17
+ /**
18
+ * Create the nx-ci job operation (Nx-specific)
19
+ */
20
+ function createNxCiJobOperation(ctx) {
21
+ const { config } = ctx;
22
+ const nxConfig = config.nx;
23
+ const packageManager = config.packageManager || 'npm';
24
+ const enableCache = nxConfig.enableCache !== false;
25
+ const taskSteps = nxConfig.tasks
26
+ .map(task => ` - name: Run Nx Affected - ${task}
27
+ run: npx nx affected --target=${task} --base=\${{ inputs.baseRef || '${nxConfig.baseRef || 'origin/main'}' }}`)
28
+ .join('\n');
29
+ const cacheStep = enableCache
30
+ ? `
31
+ - name: Cache Nx
32
+ uses: actions/cache@v4
33
+ with:
34
+ path: .nx/cache
35
+ # Cache key includes run_number to allow saving updated cache on each run
36
+ # Nx cache accumulates computation results, so we want to save after every run
37
+ # restore-keys ensure we start from the most recent cache on this branch
38
+ key: nx-\${{ runner.os }}-\${{ hashFiles('package-lock.json') }}-\${{ github.ref_name }}-\${{ github.run_number }}
39
+ restore-keys: |
40
+ nx-\${{ runner.os }}-\${{ hashFiles('package-lock.json') }}-\${{ github.ref_name }}-
41
+ nx-\${{ runner.os }}-\${{ hashFiles('package-lock.json') }}-
42
+ nx-\${{ runner.os }}-
43
+ `
44
+ : '';
45
+ return {
46
+ path: 'jobs.nx-ci',
47
+ operation: 'overwrite',
48
+ commentBefore: `
49
+ =============================================================================
50
+ NX CI - All Tasks Sequential (⚠️ Managed by Pipecraft - do not modify)
51
+ =============================================================================
52
+ This job runs all Nx tasks sequentially using \`nx affected\`.
53
+ Nx handles dependency detection, caching, and parallel execution internally.
54
+ `,
55
+ value: createValueFromString(`
56
+ needs: changes
57
+ runs-on: ubuntu-latest
58
+ steps:
59
+ - name: Checkout Code
60
+ uses: actions/checkout@v4
61
+ with:
62
+ ref: \${{ inputs.commitSha || github.sha }}
63
+ fetch-depth: 0
64
+
65
+ - name: Setup Node.js
66
+ uses: actions/setup-node@v4
67
+ with:
68
+ node-version: '24'
69
+
70
+ - name: Install Dependencies
71
+ run: |
72
+ case "${packageManager}" in
73
+ pnpm)
74
+ corepack enable
75
+ pnpm install --frozen-lockfile || pnpm install
76
+ ;;
77
+ yarn)
78
+ yarn install --frozen-lockfile || yarn install
79
+ ;;
80
+ npm)
81
+ npm ci || npm install
82
+ ;;
83
+ *)
84
+ npm install
85
+ ;;
86
+ esac
87
+ env:
88
+ packageManager: ${packageManager}
89
+ ${cacheStep}
90
+ ${taskSteps}
91
+ `)
92
+ };
93
+ }
94
+ /**
95
+ * Main generator that handles merging with existing workflow
96
+ */
97
+ export const generate = (ctx) => Promise.resolve(ctx)
98
+ .then(ctx => {
99
+ const filePath = `${ctx.cwd || process.cwd()}/.github/workflows/pipeline.yml`;
100
+ const { config, branchFlow } = ctx;
101
+ const domains = config.domains || {};
102
+ const nxConfig = config.nx;
103
+ // Get domain job names for dependency management
104
+ const { testJobs, deployJobs, remoteTestJobs } = getDomainJobNames(domains);
105
+ // Build operations array
106
+ const operations = [
107
+ // Header (name, run-name, on triggers)
108
+ ...createHeaderOperations({ branchFlow }),
109
+ // Changes detection (Nx-enabled)
110
+ createChangesJobOperation({
111
+ domains,
112
+ useNx: true,
113
+ baseRef: nxConfig.baseRef || 'origin/main'
114
+ }),
115
+ // Nx CI job (Nx-specific!)
116
+ createNxCiJobOperation(ctx),
117
+ // Domain test jobs (preserved for user customization)
118
+ ...createDomainTestJobOperations({ domains }),
119
+ // Version calculation
120
+ createVersionJobOperation({
121
+ testJobNames: testJobs,
122
+ nxEnabled: true,
123
+ baseRef: nxConfig.baseRef || 'origin/main'
124
+ }),
125
+ // Domain deploy jobs (preserved for user customization)
126
+ ...createDomainDeployJobOperations({ domains }),
127
+ // Domain remote test jobs (preserved for user customization)
128
+ ...createDomainRemoteTestJobOperations({ domains }),
129
+ // Tag, promote, release
130
+ ...createTagPromoteReleaseOperations({
131
+ branchFlow,
132
+ deployJobNames: deployJobs,
133
+ remoteTestJobNames: remoteTestJobs
134
+ })
135
+ ];
136
+ // Check if file exists
137
+ if (!fs.existsSync(filePath)) {
138
+ logger.verbose('📝 Creating new Nx pipeline');
139
+ // Create new document with empty YAML map
140
+ const doc = parseDocument('{}');
141
+ if (doc.contents) {
142
+ applyPathOperations(doc.contents, operations, doc);
143
+ }
144
+ const yamlContent = stringify(doc, { lineWidth: 0, minContentWidth: 0 });
145
+ const formattedContent = formatIfConditions(yamlContent);
146
+ return { ...ctx, yamlContent: formattedContent, mergeStatus: 'created' };
147
+ }
148
+ // Parse existing file
149
+ const existingContent = fs.readFileSync(filePath, 'utf8');
150
+ const doc = parseDocument(existingContent);
151
+ // Get managed jobs (always overwritten)
152
+ const managedJobs = new Set(['changes', 'nx-ci', 'version', 'tag', 'promote', 'release']);
153
+ // Extract user jobs from existing (preserves comments!)
154
+ const userJobs = new Map();
155
+ const existingJobs = doc.contents && doc.contents.get ? doc.contents.get('jobs') : null;
156
+ if (existingJobs && existingJobs.items) {
157
+ for (const item of existingJobs.items) {
158
+ const jobName = item.key?.toString();
159
+ if (jobName && !managedJobs.has(jobName) && !testJobs.includes(jobName) && !deployJobs.includes(jobName) && !remoteTestJobs.includes(jobName)) {
160
+ // This is a custom user job - preserve it completely
161
+ userJobs.set(jobName, item);
162
+ }
163
+ }
164
+ }
165
+ // Clear all jobs before applying operations to prevent duplicates
166
+ if (existingJobs && existingJobs.items) {
167
+ ;
168
+ existingJobs.items = [];
169
+ }
170
+ // Apply operations to update managed jobs
171
+ if (doc.contents) {
172
+ applyPathOperations(doc.contents, operations, doc);
173
+ }
174
+ // Add back user jobs (preserves their comments!)
175
+ if (userJobs.size > 0) {
176
+ logger.verbose(`📋 Preserving ${userJobs.size} user jobs: ${Array.from(userJobs.keys()).join(', ')}`);
177
+ const jobsNode = doc.contents.get('jobs');
178
+ if (jobsNode && jobsNode.items) {
179
+ for (const [_, item] of userJobs) {
180
+ jobsNode.items.push(item);
181
+ }
182
+ }
183
+ }
184
+ const status = userJobs.size > 0 ? 'merged' : 'updated';
185
+ const yamlContent = stringify(doc, { lineWidth: 0, minContentWidth: 0 });
186
+ const formattedContent = formatIfConditions(yamlContent);
187
+ return { ...ctx, yamlContent: formattedContent, mergeStatus: status };
188
+ })
189
+ .then(ctx => {
190
+ const outputPath = ctx.outputPipelinePath || '.github/workflows/pipeline.yml';
191
+ const status = ctx.mergeStatus === 'merged' ? '🔄 Merged with existing' : ctx.mergeStatus === 'updated' ? '🔄 Updated existing' : '📝 Created new';
192
+ logger.verbose(`${status} ${outputPath}`);
193
+ return ctx;
194
+ })
195
+ .then(renderTemplate((ctx) => ctx.yamlContent, toFile((ctx) => ctx.outputPipelinePath || '.github/workflows/pipeline.yml')));
196
+ //# sourceMappingURL=pipeline-nx.yml.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-nx.yml.tpl.js","sourceRoot":"","sources":["../../../src/templates/workflows/pipeline-nx.yml.tpl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Path-Based Pipeline Template
3
+ *
4
+ * Generates a workflow that uses path-based change detection to identify which domains
5
+ * have changed and runs appropriate test/deploy jobs.
6
+ *
7
+ * Uses shared operations architecture for maintainability and consistency with Nx template.
8
+ */
9
+ import { PinionContext } from '@featherscloud/pinion';
10
+ import { PipecraftConfig } from '../../types/index.js';
11
+ interface PathBasedPipelineContext extends PinionContext {
12
+ config: PipecraftConfig;
13
+ branchFlow: string[];
14
+ domains: Record<string, any>;
15
+ outputPipelinePath?: string;
16
+ }
17
+ /**
18
+ * Main generator that handles merging with existing workflow
19
+ */
20
+ export declare const generate: (ctx: PathBasedPipelineContext) => Promise<any>;
21
+ export {};
22
+ //# sourceMappingURL=pipeline.yml.tpl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.yml.tpl.d.ts","sourceRoot":"","sources":["../../../src/templates/workflows/pipeline.yml.tpl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAA0B,MAAM,uBAAuB,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAiBtD,UAAU,wBAAyB,SAAQ,aAAa;IACtD,MAAM,EAAE,eAAe,CAAA;IACvB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,wBAAwB,iBA+IoF,CAAA"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Path-Based Pipeline Template
3
+ *
4
+ * Generates a workflow that uses path-based change detection to identify which domains
5
+ * have changed and runs appropriate test/deploy jobs.
6
+ *
7
+ * Uses shared operations architecture for maintainability and consistency with Nx template.
8
+ */
9
+ import { renderTemplate, toFile } from '@featherscloud/pinion';
10
+ import { parseDocument, stringify } from 'yaml';
11
+ import fs from 'fs';
12
+ import { logger } from '../../utils/logger.js';
13
+ import { applyPathOperations } from '../../utils/ast-path-operations.js';
14
+ import { formatIfConditions } from '../yaml-format-utils.js';
15
+ import { createHeaderOperations, createChangesJobOperation, createDomainTestJobOperations, createDomainDeployJobOperations, createDomainRemoteTestJobOperations, createVersionJobOperation, createTagPromoteReleaseOperations, getDomainJobNames } from './shared/index.js';
16
+ /**
17
+ * Main generator that handles merging with existing workflow
18
+ */
19
+ export const generate = (ctx) => Promise.resolve(ctx)
20
+ .then(ctx => {
21
+ const filePath = `${ctx.cwd || process.cwd()}/.github/workflows/pipeline.yml`;
22
+ const { config, branchFlow } = ctx;
23
+ const domains = config?.domains || {};
24
+ // Get domain job names for dependency management
25
+ const { testJobs, deployJobs, remoteTestJobs } = getDomainJobNames(domains);
26
+ // Build operations array
27
+ const operations = [
28
+ // Header (name, run-name, on triggers)
29
+ ...createHeaderOperations({ branchFlow }),
30
+ // Changes detection (path-based)
31
+ createChangesJobOperation({
32
+ domains,
33
+ useNx: false,
34
+ baseRef: config.finalBranch
35
+ }),
36
+ // NO nx-ci job for path-based (that's the key difference!)
37
+ // Domain test jobs (preserved for user customization)
38
+ ...createDomainTestJobOperations({ domains }),
39
+ // Version calculation
40
+ createVersionJobOperation({
41
+ testJobNames: testJobs,
42
+ nxEnabled: false,
43
+ baseRef: config.finalBranch
44
+ }),
45
+ // Domain deploy jobs (preserved for user customization)
46
+ ...createDomainDeployJobOperations({ domains }),
47
+ // Domain remote test jobs (preserved for user customization)
48
+ ...createDomainRemoteTestJobOperations({ domains }),
49
+ // Tag, promote, release
50
+ ...createTagPromoteReleaseOperations({
51
+ branchFlow,
52
+ deployJobNames: deployJobs,
53
+ remoteTestJobNames: remoteTestJobs
54
+ })
55
+ ];
56
+ // Check if file exists
57
+ if (!fs.existsSync(filePath)) {
58
+ logger.verbose('📝 Creating new path-based pipeline');
59
+ // Create new document with empty YAML map
60
+ const doc = parseDocument('{}');
61
+ if (doc.contents) {
62
+ applyPathOperations(doc.contents, operations, doc);
63
+ }
64
+ const yamlContent = stringify(doc, { lineWidth: 0, minContentWidth: 0 });
65
+ const formattedContent = formatIfConditions(yamlContent);
66
+ return { ...ctx, yamlContent: formattedContent, mergeStatus: 'created' };
67
+ }
68
+ // Parse existing file
69
+ const existingContent = fs.readFileSync(filePath, 'utf8');
70
+ const doc = parseDocument(existingContent);
71
+ // Get managed jobs (always overwritten)
72
+ const managedJobs = new Set(['changes', 'version', 'tag', 'promote', 'release']);
73
+ // Get deprecated jobs (should be removed)
74
+ const deprecatedJobs = new Set(['createpr', 'branch']);
75
+ // Extract user jobs from existing (preserves comments!)
76
+ const userJobs = new Map();
77
+ const existingJobs = doc.contents && doc.contents.get ? doc.contents.get('jobs') : null;
78
+ if (existingJobs && existingJobs.items) {
79
+ for (const item of existingJobs.items) {
80
+ const jobName = item.key?.toString();
81
+ if (jobName &&
82
+ !managedJobs.has(jobName) &&
83
+ !deprecatedJobs.has(jobName) &&
84
+ !testJobs.includes(jobName) &&
85
+ !deployJobs.includes(jobName) &&
86
+ !remoteTestJobs.includes(jobName)) {
87
+ // This is a custom user job - preserve it completely
88
+ userJobs.set(jobName, item);
89
+ }
90
+ }
91
+ }
92
+ // Clear all jobs before applying operations to prevent duplicates
93
+ if (existingJobs && existingJobs.items) {
94
+ ;
95
+ existingJobs.items = [];
96
+ }
97
+ // Apply operations to update managed jobs
98
+ if (doc.contents) {
99
+ applyPathOperations(doc.contents, operations, doc);
100
+ }
101
+ // Add back user jobs (preserves their comments!)
102
+ if (userJobs.size > 0) {
103
+ logger.verbose(`📋 Preserving ${userJobs.size} user jobs: ${Array.from(userJobs.keys()).join(', ')}`);
104
+ const jobsNode = doc.contents.get('jobs');
105
+ if (jobsNode && jobsNode.items) {
106
+ for (const [_, item] of userJobs) {
107
+ jobsNode.items.push(item);
108
+ }
109
+ }
110
+ }
111
+ // Check for deprecated jobs
112
+ const deprecatedFound = [];
113
+ if (existingJobs && existingJobs.items) {
114
+ for (const item of existingJobs.items) {
115
+ const jobName = item.key?.toString();
116
+ if (jobName && deprecatedJobs.has(jobName)) {
117
+ deprecatedFound.push(jobName);
118
+ }
119
+ }
120
+ }
121
+ if (deprecatedFound.length > 0) {
122
+ logger.verbose(`🗑️ Removed deprecated jobs: ${deprecatedFound.join(', ')}`);
123
+ }
124
+ const status = userJobs.size > 0 ? 'merged' : 'updated';
125
+ const yamlContent = stringify(doc, { lineWidth: 0, minContentWidth: 0 });
126
+ const formattedContent = formatIfConditions(yamlContent);
127
+ return { ...ctx, yamlContent: formattedContent, mergeStatus: status };
128
+ })
129
+ .then(ctx => {
130
+ const outputPath = ctx.outputPipelinePath || '.github/workflows/pipeline.yml';
131
+ const status = ctx.mergeStatus === 'merged' ? '🔄 Merged with existing' : ctx.mergeStatus === 'updated' ? '🔄 Updated existing' : '📝 Created new';
132
+ logger.verbose(`${status} ${outputPath}`);
133
+ return ctx;
134
+ })
135
+ .then(renderTemplate((ctx) => ctx.yamlContent, toFile((ctx) => ctx.outputPipelinePath || '.github/workflows/pipeline.yml')));
136
+ //# sourceMappingURL=pipeline.yml.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.yml.tpl.js","sourceRoot":"","sources":["../../../src/templates/workflows/pipeline.yml.tpl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAiB,cAAc,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE7E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAC/C,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAuB,mBAAmB,EAAE,MAAM,oCAAoC,CAAA;AAC7F,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,6BAA6B,EAC7B,+BAA+B,EAC/B,mCAAmC,EACnC,yBAAyB,EACzB,iCAAiC,EACjC,iBAAiB,EAClB,MAAM,mBAAmB,CAAA;AAS1B;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAA6B,EAAE,EAAE,CACxD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;KACjB,IAAI,CAAC,GAAG,CAAC,EAAE;IACV,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,iCAAiC,CAAA;IAC7E,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,CAAA;IAClC,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,EAAE,CAAA;IAErC,iDAAiD;IACjD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAE3E,yBAAyB;IACzB,MAAM,UAAU,GAA0B;QACxC,uCAAuC;QACvC,GAAG,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC;QAEzC,iCAAiC;QACjC,yBAAyB,CAAC;YACxB,OAAO;YACP,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,MAAM,CAAC,WAAW;SAC5B,CAAC;QAEF,2DAA2D;QAE3D,sDAAsD;QACtD,GAAG,6BAA6B,CAAC,EAAE,OAAO,EAAE,CAAC;QAE7C,sBAAsB;QACtB,yBAAyB,CAAC;YACxB,YAAY,EAAE,QAAQ;YACtB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,MAAM,CAAC,WAAW;SAC5B,CAAC;QAEF,wDAAwD;QACxD,GAAG,+BAA+B,CAAC,EAAE,OAAO,EAAE,CAAC;QAE/C,6DAA6D;QAC7D,GAAG,mCAAmC,CAAC,EAAE,OAAO,EAAE,CAAC;QAEnD,wBAAwB;QACxB,GAAG,iCAAiC,CAAC;YACnC,UAAU;YACV,cAAc,EAAE,UAAU;YAC1B,kBAAkB,EAAE,cAAc;SACnC,CAAC;KACH,CAAA;IAED,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAA;QAErD,0CAA0C;QAC1C,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;QAC/B,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACjB,mBAAmB,CAAC,GAAG,CAAC,QAAe,EAAE,UAAU,EAAE,GAAG,CAAC,CAAA;QAC3D,CAAC;QAED,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,CAAA;QACxE,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;QACxD,OAAO,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,CAAA;IAC1E,CAAC;IAED,sBAAsB;IACtB,MAAM,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IACzD,MAAM,GAAG,GAAG,aAAa,CAAC,eAAe,CAAC,CAAA;IAE1C,wCAAwC;IACxC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAA;IAEhF,0CAA0C;IAC1C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEtD,wDAAwD;IACxD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAe,CAAA;IACvC,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,IAAK,GAAG,CAAC,QAAgB,CAAC,GAAG,CAAC,CAAC,CAAE,GAAG,CAAC,QAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAEzG,IAAI,YAAY,IAAK,YAAoB,CAAC,KAAK,EAAE,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAA;YACpC,IACE,OAAO;gBACP,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC;gBACzB,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC;gBAC5B,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC3B,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC7B,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EACjC,CAAC;gBACD,qDAAqD;gBACrD,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,IAAI,YAAY,IAAK,YAAoB,CAAC,KAAK,EAAE,CAAC;QAChD,CAAC;QAAC,YAAoB,CAAC,KAAK,GAAG,EAAE,CAAA;IACnC,CAAC;IAED,0CAA0C;IAC1C,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,mBAAmB,CAAC,GAAG,CAAC,QAAe,EAAE,UAAU,EAAE,GAAG,CAAC,CAAA;IAC3D,CAAC;IAED,iDAAiD;IACjD,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,OAAO,CAAC,iBAAiB,QAAQ,CAAC,IAAI,eAAe,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAErG,MAAM,QAAQ,GAAI,GAAG,CAAC,QAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAClD,IAAI,QAAQ,IAAK,QAAgB,CAAC,KAAK,EAAE,CAAC;YACxC,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACjC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,MAAM,eAAe,GAAG,EAAE,CAAA;IAC1B,IAAI,YAAY,IAAK,YAAoB,CAAC,KAAK,EAAE,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAA;YACpC,IAAI,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3C,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,iCAAiC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;IACvD,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,CAAA;IACxE,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;IACxD,OAAO,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAA;AACvE,CAAC,CAAC;KACD,IAAI,CAAC,GAAG,CAAC,EAAE;IACV,MAAM,UAAU,GAAG,GAAG,CAAC,kBAAkB,IAAI,gCAAgC,CAAA;IAC7E,MAAM,MAAM,GACV,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,gBAAgB,CAAA;IACrI,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC,CAAA;IACzC,OAAO,GAAG,CAAA;AACZ,CAAC,CAAC;KACD,IAAI,CAAC,cAAc,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,kBAAkB,IAAI,gCAAgC,CAAC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shared Pipeline Operations
3
+ *
4
+ * Export all shared operation generators for building workflow templates.
5
+ */
6
+ export * from './operations-header.js';
7
+ export * from './operations-changes.js';
8
+ export * from './operations-domain-jobs.js';
9
+ export * from './operations-version.js';
10
+ export * from './operations-tag-promote.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/templates/workflows/shared/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA"}