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,256 @@
|
|
|
1
|
+
# Pipecraft Test Structure
|
|
2
|
+
|
|
3
|
+
This document outlines the complete test structure for the Pipecraft project.
|
|
4
|
+
|
|
5
|
+
## 📁 Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
tests/
|
|
9
|
+
├── unit/ # Unit tests for individual components
|
|
10
|
+
│ ├── config.test.ts # Configuration parsing tests
|
|
11
|
+
│ ├── idempotency.test.ts # Idempotency logic tests
|
|
12
|
+
│ ├── tag-template.test.ts # Tag template tests
|
|
13
|
+
│ └── versioning.test.ts # Versioning logic tests
|
|
14
|
+
├── integration/ # Integration tests for component interactions
|
|
15
|
+
│ └── cli.test.ts # CLI command integration tests
|
|
16
|
+
├── e2e/ # End-to-end tests for complete workflows
|
|
17
|
+
│ └── workflow-generation.test.ts # Complete workflow generation tests
|
|
18
|
+
├── github-local/ # Local GitHub Actions testing with Act
|
|
19
|
+
│ ├── README.md # Local testing documentation
|
|
20
|
+
│ └── run-local-tests.sh # Local test runner (to be created)
|
|
21
|
+
├── github-live/ # Live GitHub Actions testing
|
|
22
|
+
│ └── README.md # Live testing documentation
|
|
23
|
+
├── fixtures/ # Test data and configurations
|
|
24
|
+
│ ├── basic-config.json # Basic test configuration
|
|
25
|
+
│ └── invalid-config.json # Invalid test configuration
|
|
26
|
+
├── debugging/ # GitHub Actions debugging tools
|
|
27
|
+
│ ├── debug-workflows.sh # Workflow debugging script
|
|
28
|
+
│ ├── debug-utils.ts # Debugging utilities
|
|
29
|
+
│ ├── debug-workflow.test.ts # Debugging test suite
|
|
30
|
+
│ ├── iterative-debug.ts # Iterative debugging system
|
|
31
|
+
│ └── run-debug-tests.sh # Debug test runner
|
|
32
|
+
├── README.md # Main test documentation
|
|
33
|
+
├── setup.ts # Test setup configuration
|
|
34
|
+
└── TEST_STRUCTURE.md # This file
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 🧪 Test Categories
|
|
38
|
+
|
|
39
|
+
### 1. Unit Tests (`tests/unit/`)
|
|
40
|
+
- **Purpose**: Test individual functions, classes, and modules in isolation
|
|
41
|
+
- **Scope**: Single components with mocked dependencies
|
|
42
|
+
- **Speed**: Fast (< 1 second per test)
|
|
43
|
+
- **Examples**: Config parsing, versioning logic, template rendering
|
|
44
|
+
- **Files**: `config.test.ts`, `idempotency.test.ts`, `tag-template.test.ts`, `versioning.test.ts`
|
|
45
|
+
|
|
46
|
+
### 2. Integration Tests (`tests/integration/`)
|
|
47
|
+
- **Purpose**: Test interactions between multiple components
|
|
48
|
+
- **Scope**: Component integration with real dependencies
|
|
49
|
+
- **Speed**: Medium (1-10 seconds per test)
|
|
50
|
+
- **Examples**: CLI commands, workflow generation, configuration validation
|
|
51
|
+
- **Files**: `cli.test.ts`
|
|
52
|
+
|
|
53
|
+
### 3. End-to-End Tests (`tests/e2e/`)
|
|
54
|
+
- **Purpose**: Test complete user workflows from start to finish
|
|
55
|
+
- **Scope**: Full application flow with real file system
|
|
56
|
+
- **Speed**: Slow (10+ seconds per test)
|
|
57
|
+
- **Examples**: Complete workflow generation, version management, deployment
|
|
58
|
+
- **Files**: `workflow-generation.test.ts`
|
|
59
|
+
|
|
60
|
+
### 4. GitHub Local Testing (`tests/github-local/`)
|
|
61
|
+
- **Purpose**: Test GitHub Actions workflows locally using Act
|
|
62
|
+
- **Scope**: Local simulation of GitHub Actions environment
|
|
63
|
+
- **Speed**: Medium (5-30 seconds per test)
|
|
64
|
+
- **Examples**: Workflow execution, job dependencies, environment variables
|
|
65
|
+
- **Tools**: Act (Nectos Act)
|
|
66
|
+
- **Files**: `README.md`, `run-local-tests.sh` (to be created)
|
|
67
|
+
|
|
68
|
+
### 5. GitHub Live Testing (`tests/github-live/`)
|
|
69
|
+
- **Purpose**: Test workflows on actual GitHub Actions
|
|
70
|
+
- **Scope**: Real GitHub environment with live workflows
|
|
71
|
+
- **Speed**: Slow (1-10 minutes per test)
|
|
72
|
+
- **Examples**: Live workflow execution, performance testing, debugging
|
|
73
|
+
- **Tools**: GitHub CLI, GitHub Actions API
|
|
74
|
+
- **Files**: `README.md`, `run-live-tests.sh` (to be created)
|
|
75
|
+
|
|
76
|
+
### 6. Debugging Tools (`tests/debugging/`)
|
|
77
|
+
- **Purpose**: Debug and analyze GitHub Actions failures
|
|
78
|
+
- **Scope**: Workflow analysis, log parsing, failure diagnosis
|
|
79
|
+
- **Speed**: Variable (depends on analysis depth)
|
|
80
|
+
- **Examples**: Workflow debugging, failure analysis, iterative fixing
|
|
81
|
+
- **Files**: `debug-workflows.sh`, `debug-utils.ts`, `debug-workflow.test.ts`, `iterative-debug.ts`, `run-debug-tests.sh`
|
|
82
|
+
|
|
83
|
+
## 🚀 Running Tests
|
|
84
|
+
|
|
85
|
+
### All Tests
|
|
86
|
+
```bash
|
|
87
|
+
# Run all test suites
|
|
88
|
+
pnpm test
|
|
89
|
+
|
|
90
|
+
# Run with coverage
|
|
91
|
+
pnpm test:coverage
|
|
92
|
+
|
|
93
|
+
# Run in watch mode
|
|
94
|
+
pnpm test:watch
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Specific Test Types
|
|
98
|
+
```bash
|
|
99
|
+
# Unit tests only
|
|
100
|
+
pnpm test tests/unit/
|
|
101
|
+
|
|
102
|
+
# Integration tests only
|
|
103
|
+
pnpm test tests/integration/
|
|
104
|
+
|
|
105
|
+
# E2E tests only
|
|
106
|
+
pnpm test tests/e2e/
|
|
107
|
+
|
|
108
|
+
# GitHub local tests only
|
|
109
|
+
./tests/github-local/run-local-tests.sh
|
|
110
|
+
|
|
111
|
+
# GitHub live tests only
|
|
112
|
+
./tests/github-live/run-live-tests.sh
|
|
113
|
+
|
|
114
|
+
# Debugging tools
|
|
115
|
+
./tests/debugging/debug-workflows.sh -w "My Pipeline"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 📋 Test Requirements
|
|
119
|
+
|
|
120
|
+
### Prerequisites
|
|
121
|
+
- Node.js (v18+)
|
|
122
|
+
- pnpm
|
|
123
|
+
- Git
|
|
124
|
+
- GitHub CLI (for live testing)
|
|
125
|
+
- Act (for local GitHub Actions testing)
|
|
126
|
+
- Docker (for Act)
|
|
127
|
+
|
|
128
|
+
### Environment Variables
|
|
129
|
+
```bash
|
|
130
|
+
# For GitHub live testing
|
|
131
|
+
export GITHUB_TOKEN="your_github_token"
|
|
132
|
+
export GITHUB_REPOSITORY="owner/repo"
|
|
133
|
+
|
|
134
|
+
# For debugging
|
|
135
|
+
export GITHUB_TOKEN="your_github_token"
|
|
136
|
+
export GITHUB_REPOSITORY_OWNER="owner"
|
|
137
|
+
export GITHUB_REPOSITORY="repo"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 🔧 Test Configuration
|
|
141
|
+
|
|
142
|
+
### Vitest Configuration
|
|
143
|
+
Tests use Vitest with the following configuration:
|
|
144
|
+
- TypeScript support
|
|
145
|
+
- ES modules
|
|
146
|
+
- Coverage reporting
|
|
147
|
+
- Parallel execution
|
|
148
|
+
- Watch mode support
|
|
149
|
+
|
|
150
|
+
### Test Data
|
|
151
|
+
- **Fixtures**: `tests/fixtures/` - Static test data and configurations
|
|
152
|
+
- **Mocks**: Inline mocks for external dependencies
|
|
153
|
+
- **Temporary files**: Created and cleaned up automatically
|
|
154
|
+
|
|
155
|
+
## 📊 Test Coverage
|
|
156
|
+
|
|
157
|
+
We aim for:
|
|
158
|
+
- **Unit tests**: 90%+ coverage
|
|
159
|
+
- **Integration tests**: 80%+ coverage
|
|
160
|
+
- **E2E tests**: Critical paths covered
|
|
161
|
+
- **GitHub local tests**: All workflow types tested
|
|
162
|
+
- **Live tests**: Production-like scenarios
|
|
163
|
+
|
|
164
|
+
## 🐛 Debugging Tests
|
|
165
|
+
|
|
166
|
+
### Common Issues
|
|
167
|
+
1. **Permission errors**: Ensure test files are executable
|
|
168
|
+
2. **Environment issues**: Check required environment variables
|
|
169
|
+
3. **Dependency issues**: Run `pnpm install` to update dependencies
|
|
170
|
+
4. **GitHub API limits**: Use appropriate rate limiting for live tests
|
|
171
|
+
|
|
172
|
+
### Debug Commands
|
|
173
|
+
```bash
|
|
174
|
+
# Debug specific test
|
|
175
|
+
pnpm test tests/unit/config.test.ts --reporter=verbose
|
|
176
|
+
|
|
177
|
+
# Debug with Node inspector
|
|
178
|
+
node --inspect-brk node_modules/.bin/vitest tests/unit/config.test.ts
|
|
179
|
+
|
|
180
|
+
# Debug GitHub local tests
|
|
181
|
+
./tests/github-local/run-local-tests.sh --verbose --debug
|
|
182
|
+
|
|
183
|
+
# Debug GitHub live tests
|
|
184
|
+
./tests/github-live/run-live-tests.sh --debug --workflow "My Pipeline"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## 📝 Writing Tests
|
|
188
|
+
|
|
189
|
+
### Unit Test Example
|
|
190
|
+
```typescript
|
|
191
|
+
import { describe, it, expect } from 'vitest'
|
|
192
|
+
import { parseConfig } from '../src/utils/config'
|
|
193
|
+
|
|
194
|
+
describe('Config Parser', () => {
|
|
195
|
+
it('should parse valid configuration', () => {
|
|
196
|
+
const config = parseConfig('{"version": "1.0.0"}')
|
|
197
|
+
expect(config.version).toBe('1.0.0')
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Integration Test Example
|
|
203
|
+
```typescript
|
|
204
|
+
import { describe, it, expect } from 'vitest'
|
|
205
|
+
import { runCLI } from './helpers/cli'
|
|
206
|
+
|
|
207
|
+
describe('CLI Integration', () => {
|
|
208
|
+
it('should generate workflows', async () => {
|
|
209
|
+
const result = await runCLI(['generate'])
|
|
210
|
+
expect(result.exitCode).toBe(0)
|
|
211
|
+
})
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### E2E Test Example
|
|
216
|
+
```typescript
|
|
217
|
+
import { describe, it, expect } from 'vitest'
|
|
218
|
+
import { generateWorkflows } from './helpers/workflow'
|
|
219
|
+
|
|
220
|
+
describe('E2E Workflow Generation', () => {
|
|
221
|
+
it('should generate complete workflow suite', async () => {
|
|
222
|
+
const result = await generateWorkflows()
|
|
223
|
+
expect(result.success).toBe(true)
|
|
224
|
+
expect(result.workflows).toHaveLength(7)
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## 🔄 Continuous Integration
|
|
230
|
+
|
|
231
|
+
### GitHub Actions
|
|
232
|
+
Tests run automatically on:
|
|
233
|
+
- Pull requests
|
|
234
|
+
- Pushes to main branch
|
|
235
|
+
- Scheduled runs (nightly)
|
|
236
|
+
|
|
237
|
+
### Test Matrix
|
|
238
|
+
- Node.js versions: 18, 20, 22
|
|
239
|
+
- Operating systems: Ubuntu, macOS, Windows
|
|
240
|
+
- Test types: Unit, Integration, E2E
|
|
241
|
+
|
|
242
|
+
## 📚 Additional Resources
|
|
243
|
+
|
|
244
|
+
- [Vitest Documentation](https://vitest.dev/)
|
|
245
|
+
- [Act Documentation](https://github.com/nektos/act)
|
|
246
|
+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
|
247
|
+
- [Testing Best Practices](./testing-best-practices.md)
|
|
248
|
+
|
|
249
|
+
## 🤝 Contributing
|
|
250
|
+
|
|
251
|
+
When adding new tests:
|
|
252
|
+
1. Follow the existing structure and naming conventions
|
|
253
|
+
2. Add appropriate test data to fixtures
|
|
254
|
+
3. Update this document if adding new test categories
|
|
255
|
+
4. Ensure tests are fast and reliable
|
|
256
|
+
5. Add documentation for complex test scenarios
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Act Testing Suite Runner
|
|
4
|
+
# Tests GitHub Actions workflows locally using Act
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Colors for output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
PURPLE='\033[0;35m'
|
|
14
|
+
CYAN='\033[0;36m'
|
|
15
|
+
NC='\033[0m' # No Color
|
|
16
|
+
|
|
17
|
+
# Configuration
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
19
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
20
|
+
TESTS_DIR="$SCRIPT_DIR"
|
|
21
|
+
FIXTURES_DIR="$TESTS_DIR/fixtures"
|
|
22
|
+
OUTPUT_DIR="$TESTS_DIR/output"
|
|
23
|
+
VERBOSE=false
|
|
24
|
+
DEBUG=false
|
|
25
|
+
WORKFLOW=""
|
|
26
|
+
CLEANUP=true
|
|
27
|
+
|
|
28
|
+
# Function to print colored output
|
|
29
|
+
print_status() {
|
|
30
|
+
local status=$1
|
|
31
|
+
local message=$2
|
|
32
|
+
|
|
33
|
+
case $status in
|
|
34
|
+
"SUCCESS") echo -e "${GREEN}✓${NC} $message" ;;
|
|
35
|
+
"FAILURE") echo -e "${RED}✗${NC} $message" ;;
|
|
36
|
+
"WARNING") echo -e "${YELLOW}⚠${NC} $message" ;;
|
|
37
|
+
"INFO") echo -e "${BLUE}ℹ${NC} $message" ;;
|
|
38
|
+
"DEBUG") echo -e "${PURPLE}🐛${NC} $message" ;;
|
|
39
|
+
*) echo -e "${CYAN}?${NC} $message" ;;
|
|
40
|
+
esac
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Function to show usage
|
|
44
|
+
show_usage() {
|
|
45
|
+
cat << EOF
|
|
46
|
+
Usage: $0 [OPTIONS]
|
|
47
|
+
|
|
48
|
+
Act Testing Suite Runner
|
|
49
|
+
|
|
50
|
+
OPTIONS:
|
|
51
|
+
-w, --workflow FILE Test specific workflow file
|
|
52
|
+
-v, --verbose Verbose output
|
|
53
|
+
-d, --debug Debug mode with extra logging
|
|
54
|
+
-c, --no-cleanup Don't clean up test artifacts
|
|
55
|
+
-h, --help Show this help message
|
|
56
|
+
|
|
57
|
+
EXAMPLES:
|
|
58
|
+
$0 # Run all workflow tests
|
|
59
|
+
$0 -w pipeline.yml # Test specific workflow
|
|
60
|
+
$0 -v -d # Verbose debug mode
|
|
61
|
+
$0 -w job.changes.yml --no-cleanup # Test changes workflow, keep artifacts
|
|
62
|
+
|
|
63
|
+
EOF
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Function to check prerequisites
|
|
67
|
+
check_prerequisites() {
|
|
68
|
+
print_status "INFO" "Checking prerequisites..."
|
|
69
|
+
|
|
70
|
+
local missing_deps=()
|
|
71
|
+
|
|
72
|
+
# Check for required commands
|
|
73
|
+
if ! command -v act &> /dev/null; then
|
|
74
|
+
missing_deps+=("act")
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
if ! command -v docker &> /dev/null; then
|
|
78
|
+
missing_deps+=("docker")
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
if ! command -v jq &> /dev/null; then
|
|
82
|
+
missing_deps+=("jq")
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
if [ ${#missing_deps[@]} -gt 0 ]; then
|
|
86
|
+
print_status "FAILURE" "Missing dependencies: ${missing_deps[*]}"
|
|
87
|
+
echo -e "${YELLOW}Please install missing dependencies:${NC}"
|
|
88
|
+
for dep in "${missing_deps[@]}"; do
|
|
89
|
+
case $dep in
|
|
90
|
+
"act") echo " - Act: curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash" ;;
|
|
91
|
+
"docker") echo " - Docker: https://docs.docker.com/get-docker/" ;;
|
|
92
|
+
"jq") echo " - jq: brew install jq (macOS) or apt-get install jq (Ubuntu)" ;;
|
|
93
|
+
esac
|
|
94
|
+
done
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Check if Docker is running
|
|
99
|
+
if ! docker info &> /dev/null; then
|
|
100
|
+
print_status "FAILURE" "Docker is not running"
|
|
101
|
+
echo -e "${YELLOW}Please start Docker and try again${NC}"
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
print_status "SUCCESS" "All prerequisites satisfied"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Function to setup test environment
|
|
109
|
+
setup_test_environment() {
|
|
110
|
+
print_status "INFO" "Setting up test environment..."
|
|
111
|
+
|
|
112
|
+
# Create output directory
|
|
113
|
+
mkdir -p "$OUTPUT_DIR"
|
|
114
|
+
|
|
115
|
+
# Create test configuration
|
|
116
|
+
cat > "$PROJECT_ROOT/.actrc" << EOF
|
|
117
|
+
# Act configuration for testing
|
|
118
|
+
-P ubuntu-latest=catthehacker/ubuntu:act-latest
|
|
119
|
+
-P ubuntu-20.04=catthehacker/ubuntu:act-20.04
|
|
120
|
+
-P ubuntu-18.04=catthehacker/ubuntu:act-18.04
|
|
121
|
+
EOF
|
|
122
|
+
|
|
123
|
+
# Create test environment file
|
|
124
|
+
cat > "$PROJECT_ROOT/.env" << EOF
|
|
125
|
+
# Test environment variables
|
|
126
|
+
GITHUB_ACTIONS=true
|
|
127
|
+
GITHUB_WORKFLOW=test-workflow
|
|
128
|
+
GITHUB_RUN_ID=123456789
|
|
129
|
+
GITHUB_RUN_NUMBER=1
|
|
130
|
+
GITHUB_ACTOR=test-user
|
|
131
|
+
GITHUB_REPOSITORY=test-org/test-repo
|
|
132
|
+
GITHUB_EVENT_NAME=push
|
|
133
|
+
GITHUB_SHA=abc123def456
|
|
134
|
+
GITHUB_REF=refs/heads/main
|
|
135
|
+
GITHUB_HEAD_REF=""
|
|
136
|
+
GITHUB_BASE_REF=""
|
|
137
|
+
GITHUB_WORKSPACE=$PROJECT_ROOT
|
|
138
|
+
GITHUB_TOKEN=test-token
|
|
139
|
+
EOF
|
|
140
|
+
|
|
141
|
+
print_status "SUCCESS" "Test environment setup complete"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# Function to test a specific workflow
|
|
145
|
+
test_workflow() {
|
|
146
|
+
local workflow_file=$1
|
|
147
|
+
local workflow_name=$(basename "$workflow_file" .yml)
|
|
148
|
+
|
|
149
|
+
print_status "INFO" "Testing workflow: $workflow_name"
|
|
150
|
+
|
|
151
|
+
# Check if workflow file exists
|
|
152
|
+
if [ ! -f "$workflow_file" ]; then
|
|
153
|
+
print_status "FAILURE" "Workflow file not found: $workflow_file"
|
|
154
|
+
return 1
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
# Test workflow syntax
|
|
158
|
+
if [ "$VERBOSE" = true ]; then
|
|
159
|
+
print_status "DEBUG" "Validating workflow syntax..."
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Run Act test
|
|
163
|
+
local act_args=("-W" "$workflow_file" "--dry-run")
|
|
164
|
+
|
|
165
|
+
if [ "$VERBOSE" = true ]; then
|
|
166
|
+
act_args+=("--verbose")
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
if [ "$DEBUG" = true ]; then
|
|
170
|
+
act_args+=("--debug")
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Add environment file
|
|
174
|
+
act_args+=("--env-file" "$PROJECT_ROOT/.env")
|
|
175
|
+
|
|
176
|
+
# Run the test
|
|
177
|
+
if act "${act_args[@]}" > "$OUTPUT_DIR/${workflow_name}.log" 2>&1; then
|
|
178
|
+
print_status "SUCCESS" "Workflow $workflow_name passed"
|
|
179
|
+
return 0
|
|
180
|
+
else
|
|
181
|
+
print_status "FAILURE" "Workflow $workflow_name failed"
|
|
182
|
+
if [ "$VERBOSE" = true ]; then
|
|
183
|
+
echo "Error details:"
|
|
184
|
+
cat "$OUTPUT_DIR/${workflow_name}.log"
|
|
185
|
+
fi
|
|
186
|
+
return 1
|
|
187
|
+
fi
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# Function to test all workflows
|
|
191
|
+
test_all_workflows() {
|
|
192
|
+
print_status "INFO" "Testing all workflows..."
|
|
193
|
+
|
|
194
|
+
local workflows_dir="$PROJECT_ROOT/.github/workflows"
|
|
195
|
+
local failed_tests=0
|
|
196
|
+
local total_tests=0
|
|
197
|
+
|
|
198
|
+
# Find all workflow files
|
|
199
|
+
local workflow_files=()
|
|
200
|
+
if [ -d "$workflows_dir" ]; then
|
|
201
|
+
while IFS= read -r -d '' file; do
|
|
202
|
+
workflow_files+=("$file")
|
|
203
|
+
done < <(find "$workflows_dir" -name "*.yml" -print0)
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
if [ ${#workflow_files[@]} -eq 0 ]; then
|
|
207
|
+
print_status "WARNING" "No workflow files found in $workflows_dir"
|
|
208
|
+
return 0
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
# Test each workflow
|
|
212
|
+
for workflow_file in "${workflow_files[@]}"; do
|
|
213
|
+
total_tests=$((total_tests + 1))
|
|
214
|
+
if test_workflow "$workflow_file"; then
|
|
215
|
+
print_status "SUCCESS" "✅ $(basename "$workflow_file")"
|
|
216
|
+
else
|
|
217
|
+
print_status "FAILURE" "❌ $(basename "$workflow_file")"
|
|
218
|
+
failed_tests=$((failed_tests + 1))
|
|
219
|
+
fi
|
|
220
|
+
done
|
|
221
|
+
|
|
222
|
+
# Summary
|
|
223
|
+
echo ""
|
|
224
|
+
print_status "INFO" "Test Summary:"
|
|
225
|
+
echo " Total workflows: $total_tests"
|
|
226
|
+
echo " Passed: $((total_tests - failed_tests))"
|
|
227
|
+
echo " Failed: $failed_tests"
|
|
228
|
+
|
|
229
|
+
if [ $failed_tests -gt 0 ]; then
|
|
230
|
+
print_status "FAILURE" "Some workflows failed testing"
|
|
231
|
+
return 1
|
|
232
|
+
else
|
|
233
|
+
print_status "SUCCESS" "All workflows passed testing"
|
|
234
|
+
return 0
|
|
235
|
+
fi
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
# Function to cleanup test artifacts
|
|
239
|
+
cleanup_test_artifacts() {
|
|
240
|
+
if [ "$CLEANUP" = true ]; then
|
|
241
|
+
print_status "INFO" "Cleaning up test artifacts..."
|
|
242
|
+
|
|
243
|
+
# Remove test files
|
|
244
|
+
rm -f "$PROJECT_ROOT/.actrc"
|
|
245
|
+
rm -f "$PROJECT_ROOT/.env"
|
|
246
|
+
|
|
247
|
+
# Clean up output directory
|
|
248
|
+
if [ -d "$OUTPUT_DIR" ]; then
|
|
249
|
+
rm -rf "$OUTPUT_DIR"
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
print_status "SUCCESS" "Cleanup complete"
|
|
253
|
+
fi
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
# Function to show test results
|
|
257
|
+
show_test_results() {
|
|
258
|
+
if [ -d "$OUTPUT_DIR" ]; then
|
|
259
|
+
echo ""
|
|
260
|
+
print_status "INFO" "Test Results:"
|
|
261
|
+
echo " Output directory: $OUTPUT_DIR"
|
|
262
|
+
|
|
263
|
+
if [ "$VERBOSE" = true ]; then
|
|
264
|
+
echo " Log files:"
|
|
265
|
+
find "$OUTPUT_DIR" -name "*.log" -exec basename {} \; | while read -r log_file; do
|
|
266
|
+
echo " - $log_file"
|
|
267
|
+
done
|
|
268
|
+
fi
|
|
269
|
+
fi
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
# Parse command line arguments
|
|
273
|
+
while [[ $# -gt 0 ]]; do
|
|
274
|
+
case $1 in
|
|
275
|
+
-w|--workflow)
|
|
276
|
+
WORKFLOW="$2"
|
|
277
|
+
shift 2
|
|
278
|
+
;;
|
|
279
|
+
-v|--verbose)
|
|
280
|
+
VERBOSE=true
|
|
281
|
+
shift
|
|
282
|
+
;;
|
|
283
|
+
-d|--debug)
|
|
284
|
+
DEBUG=true
|
|
285
|
+
shift
|
|
286
|
+
;;
|
|
287
|
+
-c|--no-cleanup)
|
|
288
|
+
CLEANUP=false
|
|
289
|
+
shift
|
|
290
|
+
;;
|
|
291
|
+
-h|--help)
|
|
292
|
+
show_usage
|
|
293
|
+
exit 0
|
|
294
|
+
;;
|
|
295
|
+
*)
|
|
296
|
+
echo -e "${RED}Unknown option: $1${NC}" >&2
|
|
297
|
+
show_usage
|
|
298
|
+
exit 1
|
|
299
|
+
;;
|
|
300
|
+
esac
|
|
301
|
+
done
|
|
302
|
+
|
|
303
|
+
# Main execution
|
|
304
|
+
main() {
|
|
305
|
+
echo -e "${BLUE}Act Testing Suite${NC}"
|
|
306
|
+
echo -e "${CYAN}================${NC}"
|
|
307
|
+
echo ""
|
|
308
|
+
|
|
309
|
+
# Check prerequisites
|
|
310
|
+
check_prerequisites
|
|
311
|
+
|
|
312
|
+
# Setup test environment
|
|
313
|
+
setup_test_environment
|
|
314
|
+
|
|
315
|
+
# Run tests
|
|
316
|
+
if [ -n "$WORKFLOW" ]; then
|
|
317
|
+
# Test specific workflow
|
|
318
|
+
if test_workflow "$WORKFLOW"; then
|
|
319
|
+
print_status "SUCCESS" "Workflow test completed successfully"
|
|
320
|
+
else
|
|
321
|
+
print_status "FAILURE" "Workflow test failed"
|
|
322
|
+
exit 1
|
|
323
|
+
fi
|
|
324
|
+
else
|
|
325
|
+
# Test all workflows
|
|
326
|
+
if test_all_workflows; then
|
|
327
|
+
print_status "SUCCESS" "All workflow tests completed successfully"
|
|
328
|
+
else
|
|
329
|
+
print_status "FAILURE" "Some workflow tests failed"
|
|
330
|
+
exit 1
|
|
331
|
+
fi
|
|
332
|
+
fi
|
|
333
|
+
|
|
334
|
+
# Show results
|
|
335
|
+
show_test_results
|
|
336
|
+
|
|
337
|
+
# Cleanup
|
|
338
|
+
cleanup_test_artifacts
|
|
339
|
+
|
|
340
|
+
echo ""
|
|
341
|
+
print_status "SUCCESS" "Act testing complete!"
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
# Run main function
|
|
345
|
+
main "$@"
|