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,244 @@
|
|
|
1
|
+
import { execSync } from 'child_process'
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
|
3
|
+
import { join } from 'path'
|
|
4
|
+
import { PipecraftConfig } from '../types/index.js'
|
|
5
|
+
|
|
6
|
+
export class VersionManager {
|
|
7
|
+
private config: PipecraftConfig
|
|
8
|
+
|
|
9
|
+
constructor(config: PipecraftConfig) {
|
|
10
|
+
this.config = config
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate release-it configuration
|
|
15
|
+
*/
|
|
16
|
+
generateReleaseItConfig(): string {
|
|
17
|
+
const defaultConfig = {
|
|
18
|
+
git: {
|
|
19
|
+
requireCleanWorkingDir: false,
|
|
20
|
+
commit: false,
|
|
21
|
+
pushArgs: ["--tags"],
|
|
22
|
+
tagMatch: "v[0-9]*.[0-9]*.[0-9]*"
|
|
23
|
+
},
|
|
24
|
+
github: {
|
|
25
|
+
release: false
|
|
26
|
+
},
|
|
27
|
+
npm: {
|
|
28
|
+
ignoreVersion: true,
|
|
29
|
+
publish: false,
|
|
30
|
+
skipChecks: true
|
|
31
|
+
},
|
|
32
|
+
hooks: {
|
|
33
|
+
"after:release": "echo ${version} > .release-version"
|
|
34
|
+
},
|
|
35
|
+
plugins: {
|
|
36
|
+
"@release-it/conventional-changelog": {
|
|
37
|
+
whatBump: (commits: any[], options: any) => {
|
|
38
|
+
const defaults = {
|
|
39
|
+
test: 'ignore',
|
|
40
|
+
build: 'ignore',
|
|
41
|
+
ci: 'patch',
|
|
42
|
+
docs: 'patch',
|
|
43
|
+
chore: 'minor',
|
|
44
|
+
style: 'patch',
|
|
45
|
+
fix: 'patch',
|
|
46
|
+
perf: 'patch',
|
|
47
|
+
refactor: 'patch',
|
|
48
|
+
feat: 'minor',
|
|
49
|
+
major: 'major',
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Merge with user-defined bump rules
|
|
53
|
+
const bumpRules = { ...defaults, ...this.config.versioning?.bumpRules }
|
|
54
|
+
|
|
55
|
+
let breakings = 0
|
|
56
|
+
let features = 0
|
|
57
|
+
let levelSet = ['major', 'minor', 'patch', 'ignore']
|
|
58
|
+
|
|
59
|
+
// eslint-disable-next-line prefer-spread
|
|
60
|
+
let level = Math.min.apply(Math, commits.map(commit => {
|
|
61
|
+
let level = levelSet.indexOf(bumpRules[commit.type as keyof typeof bumpRules] || 'ignore')
|
|
62
|
+
level = level < 0 ? 3 : level
|
|
63
|
+
|
|
64
|
+
if (commit.notes.length > 0) {
|
|
65
|
+
breakings += commit.notes.length
|
|
66
|
+
}
|
|
67
|
+
if (commit.type === 'feat') {
|
|
68
|
+
features += 1
|
|
69
|
+
}
|
|
70
|
+
return level
|
|
71
|
+
}))
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
level: level,
|
|
75
|
+
reason: breakings === 1
|
|
76
|
+
? `There is ${breakings} BREAKING CHANGE and ${features} features`
|
|
77
|
+
: `There are ${breakings} BREAKING CHANGES and ${features} features`
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Generate commitlint configuration
|
|
89
|
+
*/
|
|
90
|
+
generateCommitlintConfig(): string {
|
|
91
|
+
return `module.exports = {
|
|
92
|
+
extends: ['@commitlint/config-conventional'],
|
|
93
|
+
rules: {
|
|
94
|
+
'type-enum': [
|
|
95
|
+
2,
|
|
96
|
+
'always',
|
|
97
|
+
[
|
|
98
|
+
'feat',
|
|
99
|
+
'fix',
|
|
100
|
+
'docs',
|
|
101
|
+
'style',
|
|
102
|
+
'refactor',
|
|
103
|
+
'perf',
|
|
104
|
+
'test',
|
|
105
|
+
'build',
|
|
106
|
+
'ci',
|
|
107
|
+
'chore',
|
|
108
|
+
'revert'
|
|
109
|
+
]
|
|
110
|
+
],
|
|
111
|
+
'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
|
|
112
|
+
'subject-empty': [2, 'never'],
|
|
113
|
+
'subject-full-stop': [2, 'never', '.'],
|
|
114
|
+
'type-case': [2, 'always', 'lower-case'],
|
|
115
|
+
'type-empty': [2, 'never']
|
|
116
|
+
}
|
|
117
|
+
}`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Generate husky configuration
|
|
122
|
+
*/
|
|
123
|
+
generateHuskyConfig(): string {
|
|
124
|
+
return `#!/usr/bin/env sh
|
|
125
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
126
|
+
|
|
127
|
+
npx commitlint --edit $1`
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Setup version management files
|
|
132
|
+
*/
|
|
133
|
+
setupVersionManagement(): void {
|
|
134
|
+
if (!this.config.versioning?.enabled) {
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Generate .release-it.cjs
|
|
139
|
+
const releaseItConfig = this.generateReleaseItConfig()
|
|
140
|
+
writeFileSync('.release-it.cjs', releaseItConfig)
|
|
141
|
+
|
|
142
|
+
// Generate commitlint.config.js
|
|
143
|
+
const commitlintConfig = this.generateCommitlintConfig()
|
|
144
|
+
writeFileSync('commitlint.config.js', commitlintConfig)
|
|
145
|
+
|
|
146
|
+
// Generate .husky/commit-msg
|
|
147
|
+
const huskyDir = '.husky'
|
|
148
|
+
if (!existsSync(huskyDir)) {
|
|
149
|
+
execSync('npx husky install', { stdio: 'inherit' })
|
|
150
|
+
// Ensure directory exists (in case husky install was mocked/failed)
|
|
151
|
+
if (!existsSync(huskyDir)) {
|
|
152
|
+
const { mkdirSync } = require('fs')
|
|
153
|
+
mkdirSync(huskyDir, { recursive: true })
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const commitMsgHook = this.generateHuskyConfig()
|
|
158
|
+
writeFileSync(join(huskyDir, 'commit-msg'), commitMsgHook)
|
|
159
|
+
execSync(`chmod +x ${join(huskyDir, 'commit-msg')}`)
|
|
160
|
+
|
|
161
|
+
// Update package.json scripts
|
|
162
|
+
this.updatePackageJsonScripts()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Update package.json with version management scripts
|
|
167
|
+
*/
|
|
168
|
+
private updatePackageJsonScripts(): void {
|
|
169
|
+
const packageJsonPath = 'package.json'
|
|
170
|
+
if (!existsSync(packageJsonPath)) {
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
175
|
+
|
|
176
|
+
packageJson.scripts = {
|
|
177
|
+
...packageJson.scripts,
|
|
178
|
+
'release': 'release-it',
|
|
179
|
+
'release:dry': 'release-it --dry-run',
|
|
180
|
+
'version:check': 'release-it --dry-run',
|
|
181
|
+
'changelog': 'conventional-changelog -p angular -i CHANGELOG.md -s',
|
|
182
|
+
'commit': 'git add . && git commit',
|
|
183
|
+
'prepare': 'husky install'
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Check if conventional commits are being used
|
|
191
|
+
*/
|
|
192
|
+
validateConventionalCommits(): boolean {
|
|
193
|
+
try {
|
|
194
|
+
const result = execSync('git log --oneline -10', { encoding: 'utf8' })
|
|
195
|
+
const commits = result.split('\n').filter(line => line.trim())
|
|
196
|
+
|
|
197
|
+
// Check if commits follow conventional format
|
|
198
|
+
const conventionalPattern = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .+/
|
|
199
|
+
|
|
200
|
+
return commits.every(commit => conventionalPattern.test(commit))
|
|
201
|
+
} catch (error) {
|
|
202
|
+
return false
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Get current version from git tags
|
|
208
|
+
*/
|
|
209
|
+
getCurrentVersion(): string {
|
|
210
|
+
try {
|
|
211
|
+
const result = execSync('git describe --tags --abbrev=0', { encoding: 'utf8' })
|
|
212
|
+
return result.trim().replace('v', '')
|
|
213
|
+
} catch (error) {
|
|
214
|
+
return '0.0.0'
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Calculate next version based on conventional commits
|
|
220
|
+
*/
|
|
221
|
+
calculateNextVersion(): { version: string, type: string } {
|
|
222
|
+
try {
|
|
223
|
+
const currentVersion = this.getCurrentVersion()
|
|
224
|
+
const result = execSync('npx release-it --dry-run --no-git.requireCleanWorkingDir', {
|
|
225
|
+
encoding: 'utf8',
|
|
226
|
+
stdio: 'pipe'
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// Parse release-it output to get version info
|
|
230
|
+
const versionMatch = result.match(/version\s+(\d+\.\d+\.\d+)/)
|
|
231
|
+
const typeMatch = result.match(/bump\s+(\w+)/)
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
version: versionMatch ? versionMatch[1] : currentVersion,
|
|
235
|
+
type: typeMatch ? typeMatch[1] : 'patch'
|
|
236
|
+
}
|
|
237
|
+
} catch (error) {
|
|
238
|
+
return {
|
|
239
|
+
version: this.getCurrentVersion(),
|
|
240
|
+
type: 'patch'
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
package/tests/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Pipecraft Test Suite
|
|
2
|
+
|
|
3
|
+
This directory contains a comprehensive test suite for the Pipecraft project, organized by testing type and purpose.
|
|
4
|
+
|
|
5
|
+
## 📁 Test Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
tests/
|
|
9
|
+
├── unit/ # Unit tests for individual components
|
|
10
|
+
├── integration/ # Integration tests for component interactions
|
|
11
|
+
├── e2e/ # End-to-end tests for complete workflows
|
|
12
|
+
├── github-local/ # Local GitHub Actions testing with Act
|
|
13
|
+
├── github-live/ # Live GitHub Actions testing
|
|
14
|
+
├── fixtures/ # Test data and configurations
|
|
15
|
+
├── debugging/ # GitHub Actions debugging tools
|
|
16
|
+
└── README.md # This file
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 🧪 Test Categories
|
|
20
|
+
|
|
21
|
+
### Unit Tests (`tests/unit/`)
|
|
22
|
+
- **Purpose**: Test individual functions, classes, and modules in isolation
|
|
23
|
+
- **Scope**: Single components with mocked dependencies
|
|
24
|
+
- **Speed**: Fast (< 1 second per test)
|
|
25
|
+
- **Examples**: Config parsing, versioning logic, template rendering
|
|
26
|
+
|
|
27
|
+
### Integration Tests (`tests/integration/`)
|
|
28
|
+
- **Purpose**: Test interactions between multiple components
|
|
29
|
+
- **Scope**: Component integration with real dependencies
|
|
30
|
+
- **Speed**: Medium (1-10 seconds per test)
|
|
31
|
+
- **Examples**: CLI commands, workflow generation, configuration validation
|
|
32
|
+
|
|
33
|
+
### End-to-End Tests (`tests/e2e/`)
|
|
34
|
+
- **Purpose**: Test complete user workflows from start to finish
|
|
35
|
+
- **Scope**: Full application flow with real file system
|
|
36
|
+
- **Speed**: Slow (10+ seconds per test)
|
|
37
|
+
- **Examples**: Complete workflow generation, version management, deployment
|
|
38
|
+
|
|
39
|
+
### GitHub Local Testing (`tests/github-local/`)
|
|
40
|
+
- **Purpose**: Test GitHub Actions workflows locally using Act
|
|
41
|
+
- **Scope**: Local simulation of GitHub Actions environment
|
|
42
|
+
- **Speed**: Medium (5-30 seconds per test)
|
|
43
|
+
- **Examples**: Workflow execution, job dependencies, environment variables
|
|
44
|
+
|
|
45
|
+
### GitHub Live Testing (`tests/github-live/`)
|
|
46
|
+
- **Purpose**: Test workflows on actual GitHub Actions
|
|
47
|
+
- **Scope**: Real GitHub environment with live workflows
|
|
48
|
+
- **Speed**: Slow (1-10 minutes per test)
|
|
49
|
+
- **Examples**: Live workflow execution, performance testing, debugging
|
|
50
|
+
|
|
51
|
+
### Debugging Tools (`tests/debugging/`)
|
|
52
|
+
- **Purpose**: Debug and analyze GitHub Actions failures
|
|
53
|
+
- **Scope**: Workflow analysis, log parsing, failure diagnosis
|
|
54
|
+
- **Speed**: Variable (depends on analysis depth)
|
|
55
|
+
- **Examples**: Workflow debugging, failure analysis, iterative fixing
|
|
56
|
+
|
|
57
|
+
## 🚀 Running Tests
|
|
58
|
+
|
|
59
|
+
### All Tests
|
|
60
|
+
```bash
|
|
61
|
+
# Run all test suites
|
|
62
|
+
pnpm test
|
|
63
|
+
|
|
64
|
+
# Run with coverage
|
|
65
|
+
pnpm test:coverage
|
|
66
|
+
|
|
67
|
+
# Run in watch mode
|
|
68
|
+
pnpm test:watch
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Specific Test Types
|
|
72
|
+
```bash
|
|
73
|
+
# Unit tests only
|
|
74
|
+
pnpm test tests/unit/
|
|
75
|
+
|
|
76
|
+
# Integration tests only
|
|
77
|
+
pnpm test tests/integration/
|
|
78
|
+
|
|
79
|
+
# E2E tests only
|
|
80
|
+
pnpm test tests/e2e/
|
|
81
|
+
|
|
82
|
+
# GitHub local tests only
|
|
83
|
+
./tests/github-local/run-local-tests.sh
|
|
84
|
+
|
|
85
|
+
# GitHub live tests only
|
|
86
|
+
./tests/github-live/run-live-tests.sh
|
|
87
|
+
|
|
88
|
+
# Debugging tools
|
|
89
|
+
./tests/debugging/debug-workflows.sh -w "My Pipeline"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 📋 Test Requirements
|
|
93
|
+
|
|
94
|
+
### Prerequisites
|
|
95
|
+
- Node.js (v18+)
|
|
96
|
+
- pnpm
|
|
97
|
+
- Git
|
|
98
|
+
- GitHub CLI (for live testing)
|
|
99
|
+
- Act (for local GitHub Actions testing)
|
|
100
|
+
|
|
101
|
+
### Environment Variables
|
|
102
|
+
```bash
|
|
103
|
+
# For GitHub live testing
|
|
104
|
+
export GITHUB_TOKEN="your_github_token"
|
|
105
|
+
export GITHUB_REPOSITORY="owner/repo"
|
|
106
|
+
|
|
107
|
+
# For debugging
|
|
108
|
+
export GITHUB_TOKEN="your_github_token"
|
|
109
|
+
export GITHUB_REPOSITORY_OWNER="owner"
|
|
110
|
+
export GITHUB_REPOSITORY="repo"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 🔧 Test Configuration
|
|
114
|
+
|
|
115
|
+
### Vitest Configuration
|
|
116
|
+
Tests use Vitest with the following configuration:
|
|
117
|
+
- TypeScript support
|
|
118
|
+
- ES modules
|
|
119
|
+
- Coverage reporting
|
|
120
|
+
- Parallel execution
|
|
121
|
+
- Watch mode support
|
|
122
|
+
|
|
123
|
+
### Test Data
|
|
124
|
+
- **Fixtures**: `tests/fixtures/` - Static test data and configurations
|
|
125
|
+
- **Mocks**: Inline mocks for external dependencies
|
|
126
|
+
- **Temporary files**: Created and cleaned up automatically
|
|
127
|
+
|
|
128
|
+
## 📊 Test Coverage
|
|
129
|
+
|
|
130
|
+
We aim for:
|
|
131
|
+
- **Unit tests**: 90%+ coverage
|
|
132
|
+
- **Integration tests**: 80%+ coverage
|
|
133
|
+
- **E2E tests**: Critical paths covered
|
|
134
|
+
- **Act tests**: All workflow types tested
|
|
135
|
+
- **Live tests**: Production-like scenarios
|
|
136
|
+
|
|
137
|
+
## 🐛 Debugging Tests
|
|
138
|
+
|
|
139
|
+
### Common Issues
|
|
140
|
+
1. **Permission errors**: Ensure test files are executable
|
|
141
|
+
2. **Environment issues**: Check required environment variables
|
|
142
|
+
3. **Dependency issues**: Run `pnpm install` to update dependencies
|
|
143
|
+
4. **GitHub API limits**: Use appropriate rate limiting for live tests
|
|
144
|
+
|
|
145
|
+
### Debug Commands
|
|
146
|
+
```bash
|
|
147
|
+
# Debug specific test
|
|
148
|
+
pnpm test tests/unit/config.test.ts --reporter=verbose
|
|
149
|
+
|
|
150
|
+
# Debug with Node inspector
|
|
151
|
+
node --inspect-brk node_modules/.bin/vitest tests/unit/config.test.ts
|
|
152
|
+
|
|
153
|
+
# Debug Act tests
|
|
154
|
+
./tests/act/run-act-tests.sh --verbose --debug
|
|
155
|
+
|
|
156
|
+
# Debug GitHub live tests
|
|
157
|
+
./tests/github-live/run-live-tests.sh --debug --workflow "My Pipeline"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 📝 Writing Tests
|
|
161
|
+
|
|
162
|
+
### Unit Test Example
|
|
163
|
+
```typescript
|
|
164
|
+
import { describe, it, expect } from 'vitest'
|
|
165
|
+
import { parseConfig } from '../src/utils/config'
|
|
166
|
+
|
|
167
|
+
describe('Config Parser', () => {
|
|
168
|
+
it('should parse valid configuration', () => {
|
|
169
|
+
const config = parseConfig('{"version": "1.0.0"}')
|
|
170
|
+
expect(config.version).toBe('1.0.0')
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Integration Test Example
|
|
176
|
+
```typescript
|
|
177
|
+
import { describe, it, expect } from 'vitest'
|
|
178
|
+
import { runCLI } from './helpers/cli'
|
|
179
|
+
|
|
180
|
+
describe('CLI Integration', () => {
|
|
181
|
+
it('should generate workflows', async () => {
|
|
182
|
+
const result = await runCLI(['generate'])
|
|
183
|
+
expect(result.exitCode).toBe(0)
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### E2E Test Example
|
|
189
|
+
```typescript
|
|
190
|
+
import { describe, it, expect } from 'vitest'
|
|
191
|
+
import { generateWorkflows } from './helpers/workflow'
|
|
192
|
+
|
|
193
|
+
describe('E2E Workflow Generation', () => {
|
|
194
|
+
it('should generate complete workflow suite', async () => {
|
|
195
|
+
const result = await generateWorkflows()
|
|
196
|
+
expect(result.success).toBe(true)
|
|
197
|
+
expect(result.workflows).toHaveLength(7)
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 🔄 Continuous Integration
|
|
203
|
+
|
|
204
|
+
### GitHub Actions
|
|
205
|
+
Tests run automatically on:
|
|
206
|
+
- Pull requests
|
|
207
|
+
- Pushes to main branch
|
|
208
|
+
- Scheduled runs (nightly)
|
|
209
|
+
|
|
210
|
+
### Test Matrix
|
|
211
|
+
- Node.js versions: 18, 20, 22
|
|
212
|
+
- Operating systems: Ubuntu, macOS, Windows
|
|
213
|
+
- Test types: Unit, Integration, E2E
|
|
214
|
+
|
|
215
|
+
## 📚 Additional Resources
|
|
216
|
+
|
|
217
|
+
- [Vitest Documentation](https://vitest.dev/)
|
|
218
|
+
- [Act Documentation](https://github.com/nektos/act)
|
|
219
|
+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
|
220
|
+
- [Testing Best Practices](./testing-best-practices.md)
|
|
221
|
+
|
|
222
|
+
## 🤝 Contributing
|
|
223
|
+
|
|
224
|
+
When adding new tests:
|
|
225
|
+
1. Follow the existing structure and naming conventions
|
|
226
|
+
2. Add appropriate test data to fixtures
|
|
227
|
+
3. Update this README if adding new test categories
|
|
228
|
+
4. Ensure tests are fast and reliable
|
|
229
|
+
5. Add documentation for complex test scenarios
|