pipecraft 0.0.0-releaseit
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +35 -0
- package/.github/actions/calculate-version/action.yml +106 -0
- package/.github/actions/create-pr/action.yml +122 -0
- package/.github/actions/create-release/action.yml +74 -0
- package/.github/actions/create-tag/action.yml +94 -0
- package/.github/actions/detect-changes/action.yml +62 -0
- package/.github/actions/manage-branch/action.yml +113 -0
- package/.github/actions/promote-branch/action.yml +352 -0
- package/.github/example/workflows/job.analyze.code.yml +26 -0
- package/.github/example/workflows/job.analyze.docker.yml +32 -0
- package/.github/example/workflows/job.app.api.deploy.yml +127 -0
- package/.github/example/workflows/job.app.api.test.yml +102 -0
- package/.github/example/workflows/job.app.docs.deploy.yml +40 -0
- package/.github/example/workflows/job.app.docs.test.yml +50 -0
- package/.github/example/workflows/job.app.web.deploy.yml +96 -0
- package/.github/example/workflows/job.app.web.test.yml +49 -0
- package/.github/example/workflows/job.changes.yml +82 -0
- package/.github/example/workflows/job.create-pr.yml +96 -0
- package/.github/example/workflows/job.env-check.yml +43 -0
- package/.github/example/workflows/job.fast-forward.yml +103 -0
- package/.github/example/workflows/job.lint.yml +64 -0
- package/.github/example/workflows/job.pr-name.yml +70 -0
- package/.github/example/workflows/job.pr-squash-name.yml +27 -0
- package/.github/example/workflows/job.tag.yml +38 -0
- package/.github/example/workflows/job.version.yml +99 -0
- package/.github/example/workflows/lib.plugin-base.publish.yml +59 -0
- package/.github/example/workflows/pipe.yml +178 -0
- package/.github/example/workflows/scripts/fastforward.sh +51 -0
- package/.github/example/workflows/scripts/pipe-cleaner.sh +70 -0
- package/.github/scripts/fastforward.sh +51 -0
- package/.github/scripts/pipe-cleaner.sh +70 -0
- package/.github/workflows/pipeline.yml +220 -0
- package/.github/workflows/pr-title-check.yml +70 -0
- package/.github/workflows/publish.yml +39 -0
- package/.pipecraftrc.json +78 -0
- package/.release-it.cjs +71 -0
- package/PIPELINE_TESTING_PLAN.md +499 -0
- package/README.md +1101 -0
- package/TRUNK_FLOW_PLAN.md +401 -0
- package/assets/logo_banner.png +0 -0
- package/assets/logo_banner.webp +0 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +364 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/generators/init.tpl.d.ts +3 -0
- package/dist/generators/init.tpl.d.ts.map +1 -0
- package/dist/generators/init.tpl.js +117 -0
- package/dist/generators/init.tpl.js.map +1 -0
- package/dist/generators/workflows.tpl.d.ts +7 -0
- package/dist/generators/workflows.tpl.d.ts.map +1 -0
- package/dist/generators/workflows.tpl.js +73 -0
- package/dist/generators/workflows.tpl.js.map +1 -0
- package/dist/templates/actions/calculate-version.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/calculate-version.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/calculate-version.yml.tpl.js +122 -0
- package/dist/templates/actions/calculate-version.yml.tpl.js.map +1 -0
- package/dist/templates/actions/create-pr.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/create-pr.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/create-pr.yml.tpl.js +145 -0
- package/dist/templates/actions/create-pr.yml.tpl.js.map +1 -0
- package/dist/templates/actions/create-tag.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/create-tag.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/create-tag.yml.tpl.js +111 -0
- package/dist/templates/actions/create-tag.yml.tpl.js.map +1 -0
- package/dist/templates/actions/detect-changes.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/detect-changes.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/detect-changes.yml.tpl.js +79 -0
- package/dist/templates/actions/detect-changes.yml.tpl.js.map +1 -0
- package/dist/templates/actions/manage-branch.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/manage-branch.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/manage-branch.yml.tpl.js +130 -0
- package/dist/templates/actions/manage-branch.yml.tpl.js.map +1 -0
- package/dist/templates/actions/promote-branch.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/promote-branch.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/promote-branch.yml.tpl.js +362 -0
- package/dist/templates/actions/promote-branch.yml.tpl.js.map +1 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts +16 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts.map +1 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.js +652 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.js.map +1 -0
- package/dist/types/index.d.ts +63 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/ast-path-operations.d.ts +287 -0
- package/dist/utils/ast-path-operations.d.ts.map +1 -0
- package/dist/utils/ast-path-operations.js +419 -0
- package/dist/utils/ast-path-operations.js.map +1 -0
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +49 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/github-setup.d.ts +74 -0
- package/dist/utils/github-setup.d.ts.map +1 -0
- package/dist/utils/github-setup.js +418 -0
- package/dist/utils/github-setup.js.map +1 -0
- package/dist/utils/idempotency.d.ts +47 -0
- package/dist/utils/idempotency.d.ts.map +1 -0
- package/dist/utils/idempotency.js +176 -0
- package/dist/utils/idempotency.js.map +1 -0
- package/dist/utils/preflight.d.ts +55 -0
- package/dist/utils/preflight.d.ts.map +1 -0
- package/dist/utils/preflight.js +261 -0
- package/dist/utils/preflight.js.map +1 -0
- package/dist/utils/versioning.d.ts +41 -0
- package/dist/utils/versioning.d.ts.map +1 -0
- package/dist/utils/versioning.js +219 -0
- package/dist/utils/versioning.js.map +1 -0
- package/docs/USER_JOURNEY_ERRORS.md +352 -0
- package/eslint.config.js +77 -0
- package/examples/basic-config.json +41 -0
- package/examples/monorepo-config.json +49 -0
- package/examples/usage.md +289 -0
- package/package.json +58 -0
- package/scripts/debug-workflows.sh +339 -0
- package/scripts/parse-pipeline.js +29 -0
- package/scripts/test-job-order.cjs +140 -0
- package/scripts/validate-pipeline.cjs +379 -0
- package/scripts/verify-job-order.sh +30 -0
- package/src/cli/index.ts +414 -0
- package/src/generators/init.tpl.ts +126 -0
- package/src/generators/workflows.tpl.ts +80 -0
- package/src/templates/actions/calculate-version.yml.tpl.ts +124 -0
- package/src/templates/actions/create-pr.yml.tpl.ts +147 -0
- package/src/templates/actions/create-tag.yml.tpl.ts +112 -0
- package/src/templates/actions/detect-changes.yml.tpl.ts +87 -0
- package/src/templates/actions/manage-branch.yml.tpl.ts +132 -0
- package/src/templates/actions/promote-branch.yml.tpl.ts +364 -0
- package/src/templates/workflows/pipeline-path-based.yml.tpl.ts +706 -0
- package/src/types/index.ts +64 -0
- package/src/utils/README-ast-path-operations.md +390 -0
- package/src/utils/ast-path-operations.ts +581 -0
- package/src/utils/config.ts +64 -0
- package/src/utils/github-setup.ts +558 -0
- package/src/utils/idempotency.ts +215 -0
- package/src/utils/preflight.ts +306 -0
- package/src/utils/versioning.ts +244 -0
- package/tests/README.md +229 -0
- package/tests/TEST_STRUCTURE.md +256 -0
- package/tests/act/run-act-tests.sh +345 -0
- package/tests/debugging/debug-utils.ts +538 -0
- package/tests/debugging/debug-workflow.test.ts +339 -0
- package/tests/debugging/debug-workflows.sh +339 -0
- package/tests/debugging/iterative-debug.ts +652 -0
- package/tests/debugging/run-debug-tests.sh +431 -0
- package/tests/fixtures/basic-config.json +51 -0
- package/tests/fixtures/invalid-config.json +9 -0
- package/tests/fixtures/pipeline-generated.yml +235 -0
- package/tests/fixtures/pipeline-preserve-comments.yml +245 -0
- package/tests/fixtures/pipeline-user-modified.yml +245 -0
- package/tests/fixtures/test-config.json +58 -0
- package/tests/github-live/README.md +250 -0
- package/tests/github-local/JOB_WORKFLOW_TESTS.md +296 -0
- package/tests/github-local/README.md +240 -0
- package/tests/github-local/run-all-tests.sh +422 -0
- package/tests/github-local/test-job-workflows.sh +631 -0
- package/tests/github-local/test-pipeline-workflow.sh +440 -0
- package/tests/integration/generators.test.ts +578 -0
- package/tests/integration/path-based-template.test.ts +510 -0
- package/tests/integration/simple-path-based.test.ts +415 -0
- package/tests/setup.ts +56 -0
- package/tests/unit/ast-path-operations-extended.test.ts +302 -0
- package/tests/unit/cli.test.ts +541 -0
- package/tests/unit/config-extended.test.ts +412 -0
- package/tests/unit/config.test.ts +152 -0
- package/tests/unit/github-setup.test.ts +189 -0
- package/tests/unit/idempotency-isolated.test.ts +297 -0
- package/tests/unit/job-order.test.ts +157 -0
- package/tests/unit/pipeline-path-based.test.ts +511 -0
- package/tests/unit/validate-pipeline.test.ts +384 -0
- package/tests/unit/versioning-extended.test.ts +279 -0
- package/tests/unit/versioning.test.ts +241 -0
- package/tsconfig.debug.json +17 -0
- package/tsconfig.json +28 -0
- package/vitest.config.ts +51 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface DomainConfig {
|
|
2
|
+
paths: string[]
|
|
3
|
+
description: string
|
|
4
|
+
testable?: boolean
|
|
5
|
+
deployable?: boolean
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export interface PipecraftConfig {
|
|
10
|
+
ciProvider: 'github' | 'gitlab'
|
|
11
|
+
mergeStrategy: 'fast-forward' | 'merge'
|
|
12
|
+
requireConventionalCommits: boolean
|
|
13
|
+
initialBranch: string
|
|
14
|
+
finalBranch: string
|
|
15
|
+
branchFlow: string[]
|
|
16
|
+
autoMerge?: boolean | Record<string, boolean> // Auto-merge per target branch (default: false)
|
|
17
|
+
mergeMethod?: 'auto' | 'merge' | 'squash' | 'rebase' | Record<string, 'auto' | 'merge' | 'squash' | 'rebase'> // Merge method per target branch (default: 'auto' which uses fast-forward for autoMerge=true)
|
|
18
|
+
semver: {
|
|
19
|
+
bumpRules: Record<string, string>
|
|
20
|
+
}
|
|
21
|
+
actions: {
|
|
22
|
+
onDevelopMerge: string[]
|
|
23
|
+
onStagingMerge: string[]
|
|
24
|
+
}
|
|
25
|
+
domains: Record<string, DomainConfig>
|
|
26
|
+
// Idempotency and rebuild configuration
|
|
27
|
+
rebuild?: {
|
|
28
|
+
enabled: boolean
|
|
29
|
+
skipIfUnchanged: boolean
|
|
30
|
+
forceRegenerate: boolean
|
|
31
|
+
watchMode: boolean
|
|
32
|
+
hashAlgorithm: 'md5' | 'sha1' | 'sha256'
|
|
33
|
+
cacheFile: string
|
|
34
|
+
ignorePatterns: string[]
|
|
35
|
+
}
|
|
36
|
+
// Version management with release-it
|
|
37
|
+
versioning?: {
|
|
38
|
+
enabled: boolean
|
|
39
|
+
releaseItConfig: string
|
|
40
|
+
conventionalCommits: boolean
|
|
41
|
+
autoTag: boolean
|
|
42
|
+
autoPush: boolean
|
|
43
|
+
changelog: boolean
|
|
44
|
+
bumpRules: Record<string, string>
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface PipecraftContext {
|
|
49
|
+
projectName: string
|
|
50
|
+
ciProvider: 'github' | 'gitlab'
|
|
51
|
+
mergeStrategy: 'fast-forward' | 'merge'
|
|
52
|
+
requireConventionalCommits: boolean
|
|
53
|
+
initialBranch: string
|
|
54
|
+
finalBranch: string
|
|
55
|
+
branchFlow: string[]
|
|
56
|
+
domains: Record<string, { paths: string[], description: string }>
|
|
57
|
+
semver: {
|
|
58
|
+
bumpRules: Record<string, string>
|
|
59
|
+
}
|
|
60
|
+
actions: {
|
|
61
|
+
onDevelopMerge: string[]
|
|
62
|
+
onStagingMerge: string[]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# AST Path Operations for YAML Manipulation
|
|
2
|
+
|
|
3
|
+
A powerful and precise library for manipulating YAML documents using path-based operations. This library allows you to target specific locations in YAML structures and apply different types of operations with full TypeScript support.
|
|
4
|
+
|
|
5
|
+
## 🚀 Quick Start
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { applyPathOperations, createValueFromString } from './ast-path-operations'
|
|
9
|
+
import { parseDocument } from 'yaml'
|
|
10
|
+
|
|
11
|
+
// Create a YAML document
|
|
12
|
+
const doc = parseDocument(`
|
|
13
|
+
name: "Pipeline"
|
|
14
|
+
on:
|
|
15
|
+
pull_request:
|
|
16
|
+
branches: [main]
|
|
17
|
+
`)
|
|
18
|
+
|
|
19
|
+
// Define operations
|
|
20
|
+
const operations = [
|
|
21
|
+
{
|
|
22
|
+
path: 'on.workflow_call.inputs.version',
|
|
23
|
+
operation: 'set',
|
|
24
|
+
value: {
|
|
25
|
+
description: 'The version to deploy',
|
|
26
|
+
required: false,
|
|
27
|
+
type: 'string'
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
// Apply operations
|
|
33
|
+
applyPathOperations(doc.contents, operations)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 📋 Table of Contents
|
|
37
|
+
|
|
38
|
+
- [Features](#features)
|
|
39
|
+
- [Operation Types](#operation-types)
|
|
40
|
+
- [Value Types](#value-types)
|
|
41
|
+
- [API Reference](#api-reference)
|
|
42
|
+
- [Examples](#examples)
|
|
43
|
+
- [Best Practices](#best-practices)
|
|
44
|
+
|
|
45
|
+
## ✨ Features
|
|
46
|
+
|
|
47
|
+
- **🎯 Path-based targeting**: Use dot notation to target specific YAML paths
|
|
48
|
+
- **🔧 Multiple operation types**: Set, merge, overwrite, or preserve values
|
|
49
|
+
- **📦 Flexible value types**: Support objects, arrays, strings, YAML nodes, and parsed documents
|
|
50
|
+
- **🛡️ Type safety**: Full TypeScript support with proper Node types
|
|
51
|
+
- **⚡ Context injection**: Dynamic values can be injected at build time
|
|
52
|
+
- **🔄 Intelligent merging**: Smart merge logic for objects and arrays
|
|
53
|
+
|
|
54
|
+
## 🔧 Operation Types
|
|
55
|
+
|
|
56
|
+
### `set`
|
|
57
|
+
Set a value at the specified path (creates if doesn't exist)
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
{
|
|
61
|
+
path: 'jobs.changes.runs-on',
|
|
62
|
+
operation: 'set',
|
|
63
|
+
value: 'ubuntu-latest'
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `merge`
|
|
68
|
+
Merge with existing value (for objects/arrays)
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
{
|
|
72
|
+
path: 'on.pull_request.branches',
|
|
73
|
+
operation: 'merge',
|
|
74
|
+
value: ['develop', 'staging', 'main']
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `overwrite`
|
|
79
|
+
Replace existing value completely
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
{
|
|
83
|
+
path: 'jobs.changes',
|
|
84
|
+
operation: 'overwrite',
|
|
85
|
+
value: createValueFromString(`
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
steps:
|
|
88
|
+
- uses: ./.github/actions/detect-changes
|
|
89
|
+
`)
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `preserve`
|
|
94
|
+
Keep existing value, ignore template value
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
{
|
|
98
|
+
path: 'jobs.user-custom-job',
|
|
99
|
+
operation: 'preserve',
|
|
100
|
+
value: null // This will be ignored
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 📦 Value Types
|
|
105
|
+
|
|
106
|
+
### Objects
|
|
107
|
+
Simple key-value pairs for configuration
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
{
|
|
111
|
+
path: 'on.workflow_call.inputs.version',
|
|
112
|
+
operation: 'set',
|
|
113
|
+
value: {
|
|
114
|
+
description: 'The version to deploy',
|
|
115
|
+
required: false,
|
|
116
|
+
type: 'string'
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Arrays
|
|
122
|
+
Simple arrays for lists
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
{
|
|
126
|
+
path: 'on.pull_request.branches',
|
|
127
|
+
operation: 'merge',
|
|
128
|
+
value: ['develop', 'staging', 'main']
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### YAML Strings
|
|
133
|
+
Multi-line YAML with proper formatting
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
{
|
|
137
|
+
path: 'jobs.changes',
|
|
138
|
+
operation: 'overwrite',
|
|
139
|
+
value: createValueFromString(`
|
|
140
|
+
runs-on: ubuntu-latest
|
|
141
|
+
steps:
|
|
142
|
+
- uses: ./.github/actions/detect-changes
|
|
143
|
+
with:
|
|
144
|
+
baseRef: \${{ inputs.baseRef || 'main' }}
|
|
145
|
+
`)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Parsed Documents
|
|
150
|
+
Pre-parsed YAML nodes
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const parsedJob = parseDocument(`
|
|
154
|
+
runs-on: ubuntu-latest
|
|
155
|
+
steps:
|
|
156
|
+
- name: Example step
|
|
157
|
+
run: echo "Hello"
|
|
158
|
+
`)
|
|
159
|
+
|
|
160
|
+
{
|
|
161
|
+
path: 'jobs.example',
|
|
162
|
+
operation: 'set',
|
|
163
|
+
value: parsedJob.contents
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## 📚 API Reference
|
|
168
|
+
|
|
169
|
+
### Core Functions
|
|
170
|
+
|
|
171
|
+
#### `applyPathOperations(doc, operations)`
|
|
172
|
+
Apply multiple path operations to a document
|
|
173
|
+
|
|
174
|
+
**Parameters:**
|
|
175
|
+
- `doc: YAMLMap` - The YAML document to modify
|
|
176
|
+
- `operations: PathOperationConfig[]` - Array of operations to apply
|
|
177
|
+
|
|
178
|
+
#### `setPathValue(doc, path, value)`
|
|
179
|
+
Set a value at a specific path in the YAML AST
|
|
180
|
+
|
|
181
|
+
**Parameters:**
|
|
182
|
+
- `doc: YAMLMap` - The YAML document to modify
|
|
183
|
+
- `path: string` - Dot-notation path (e.g., 'jobs.changes.steps')
|
|
184
|
+
- `value: PathValue` - Value to set at the path
|
|
185
|
+
|
|
186
|
+
#### `getPathValue(doc, path)`
|
|
187
|
+
Get a value at a specific path in the YAML AST
|
|
188
|
+
|
|
189
|
+
**Parameters:**
|
|
190
|
+
- `doc: YAMLMap` - The YAML document to read from
|
|
191
|
+
- `path: string` - Dot-notation path (e.g., 'jobs.changes.steps')
|
|
192
|
+
- **Returns:** `Node | null` - The node at the path, or null if not found
|
|
193
|
+
|
|
194
|
+
### Helper Functions
|
|
195
|
+
|
|
196
|
+
#### `createValueFromString(yamlString)`
|
|
197
|
+
Create a YAML node from a YAML string
|
|
198
|
+
|
|
199
|
+
#### `createValueFromObject(obj)`
|
|
200
|
+
Create a YAML node from a JavaScript object
|
|
201
|
+
|
|
202
|
+
#### `createValueFromArray(arr)`
|
|
203
|
+
Create a YAML node from a JavaScript array
|
|
204
|
+
|
|
205
|
+
## 💡 Examples
|
|
206
|
+
|
|
207
|
+
### Basic Workflow Configuration
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { applyPathOperations, createValueFromString } from './ast-path-operations'
|
|
211
|
+
import { parseDocument } from 'yaml'
|
|
212
|
+
|
|
213
|
+
const doc = parseDocument('name: "Pipeline"')
|
|
214
|
+
|
|
215
|
+
const operations = [
|
|
216
|
+
// Set workflow inputs
|
|
217
|
+
{
|
|
218
|
+
path: 'on.workflow_call.inputs.version',
|
|
219
|
+
operation: 'set',
|
|
220
|
+
value: {
|
|
221
|
+
description: 'The version to deploy',
|
|
222
|
+
required: false,
|
|
223
|
+
type: 'string'
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
// Merge branch list
|
|
228
|
+
{
|
|
229
|
+
path: 'on.pull_request.branches',
|
|
230
|
+
operation: 'merge',
|
|
231
|
+
value: ['develop', 'staging', 'main']
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
// Overwrite job definition
|
|
235
|
+
{
|
|
236
|
+
path: 'jobs.changes',
|
|
237
|
+
operation: 'overwrite',
|
|
238
|
+
value: createValueFromString(`
|
|
239
|
+
runs-on: ubuntu-latest
|
|
240
|
+
steps:
|
|
241
|
+
- uses: ./.github/actions/detect-changes
|
|
242
|
+
with:
|
|
243
|
+
baseRef: \${{ inputs.baseRef || 'main' }}
|
|
244
|
+
`)
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
|
|
248
|
+
applyPathOperations(doc.contents, operations)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Complex Job Definitions
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
const jobOperations = [
|
|
255
|
+
{
|
|
256
|
+
path: 'jobs.test',
|
|
257
|
+
operation: 'overwrite',
|
|
258
|
+
value: createValueFromString(`
|
|
259
|
+
runs-on: ubuntu-latest
|
|
260
|
+
needs: changes
|
|
261
|
+
steps:
|
|
262
|
+
- name: Checkout code
|
|
263
|
+
uses: actions/checkout@v3
|
|
264
|
+
- name: Setup Node.js
|
|
265
|
+
uses: actions/setup-node@v3
|
|
266
|
+
with:
|
|
267
|
+
node-version: '18'
|
|
268
|
+
- name: Install dependencies
|
|
269
|
+
run: npm ci
|
|
270
|
+
- name: Run tests
|
|
271
|
+
run: npm test
|
|
272
|
+
`)
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Preserving User Customizations
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const operations = [
|
|
281
|
+
// Template-managed (always updated)
|
|
282
|
+
{
|
|
283
|
+
path: 'jobs.changes',
|
|
284
|
+
operation: 'overwrite',
|
|
285
|
+
value: createValueFromString(`...`) // Latest template
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
// User-managed (preserved)
|
|
289
|
+
{
|
|
290
|
+
path: 'jobs.user-tests',
|
|
291
|
+
operation: 'preserve',
|
|
292
|
+
value: null // User's customizations kept
|
|
293
|
+
}
|
|
294
|
+
]
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## 🎯 Best Practices
|
|
298
|
+
|
|
299
|
+
### 1. Use Appropriate Value Types
|
|
300
|
+
|
|
301
|
+
**✅ Good:**
|
|
302
|
+
```typescript
|
|
303
|
+
// Simple objects for configuration
|
|
304
|
+
{ path: 'on.workflow_call.inputs.version', value: { description: '...', type: 'string' } }
|
|
305
|
+
|
|
306
|
+
// YAML strings for complex structures
|
|
307
|
+
{ path: 'jobs.changes', value: createValueFromString(`runs-on: ubuntu-latest\nsteps: ...`) }
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**❌ Avoid:**
|
|
311
|
+
```typescript
|
|
312
|
+
// Don't use YAML strings for simple values
|
|
313
|
+
{ path: 'jobs.changes.runs-on', value: createValueFromString('ubuntu-latest') }
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### 2. Choose the Right Operation
|
|
317
|
+
|
|
318
|
+
- **`set`**: For required configuration that must exist
|
|
319
|
+
- **`merge`**: For arrays/lists where you want to add items
|
|
320
|
+
- **`overwrite`**: For template-managed sections that should get updates
|
|
321
|
+
- **`preserve`**: For user-managed sections that should keep customizations
|
|
322
|
+
|
|
323
|
+
### 3. Organize Operations by Purpose
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
const operations = [
|
|
327
|
+
// 1. Ensure required inputs exist
|
|
328
|
+
{ path: 'on.workflow_call.inputs.version', operation: 'set', value: {...} },
|
|
329
|
+
|
|
330
|
+
// 2. Merge configuration
|
|
331
|
+
{ path: 'on.pull_request.branches', operation: 'merge', value: [...] },
|
|
332
|
+
|
|
333
|
+
// 3. Overwrite template-managed jobs
|
|
334
|
+
{ path: 'jobs.changes', operation: 'overwrite', value: createValueFromString(...) },
|
|
335
|
+
|
|
336
|
+
// 4. Preserve user sections
|
|
337
|
+
{ path: 'jobs.user-tests', operation: 'preserve', value: null }
|
|
338
|
+
]
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 4. Use Context Injection
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
const operations = [
|
|
345
|
+
{
|
|
346
|
+
path: 'jobs.version',
|
|
347
|
+
operation: 'overwrite',
|
|
348
|
+
value: createValueFromString(`
|
|
349
|
+
if: github.ref_name == '${ctx.initialBranch || 'develop'}'
|
|
350
|
+
needs: changes
|
|
351
|
+
runs-on: ubuntu-latest
|
|
352
|
+
`)
|
|
353
|
+
}
|
|
354
|
+
]
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## 🔍 Troubleshooting
|
|
358
|
+
|
|
359
|
+
### Common Issues
|
|
360
|
+
|
|
361
|
+
**Path not found errors:**
|
|
362
|
+
- Ensure the path exists or use `required: false`
|
|
363
|
+
- Check for typos in dot notation paths
|
|
364
|
+
|
|
365
|
+
**Type errors:**
|
|
366
|
+
- Use proper TypeScript types for Node values
|
|
367
|
+
- Cast parsed documents correctly
|
|
368
|
+
|
|
369
|
+
**Merge conflicts:**
|
|
370
|
+
- Use `overwrite` for template-managed sections
|
|
371
|
+
- Use `preserve` for user-managed sections
|
|
372
|
+
|
|
373
|
+
### Debug Tips
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
// Check if path exists before applying
|
|
377
|
+
const existingValue = getPathValue(doc, 'jobs.changes')
|
|
378
|
+
if (existingValue) {
|
|
379
|
+
console.log('Path exists:', stringify(existingValue))
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Use console.log to debug operations
|
|
383
|
+
console.log('Applying operation:', operation)
|
|
384
|
+
applyPathOperations(doc, [operation])
|
|
385
|
+
console.log('Result:', stringify(doc))
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## 📄 License
|
|
389
|
+
|
|
390
|
+
This library is part of the Pipecraft project and follows the same licensing terms.
|