@el-j/magic-helix-plugins 4.0.0-beta.1 → 4.0.0-beta.3
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/dist/architecture/codeowners.md +123 -0
- package/dist/architecture/monorepo.md +146 -0
- package/dist/architecture/nx.md +122 -0
- package/dist/architecture/turborepo.md +114 -0
- package/dist/ci/github-actions.md +268 -0
- package/dist/ci/gitlab-ci.md +330 -0
- package/dist/containers/docker-multistage.md +120 -0
- package/dist/containers/kubernetes-deploy.md +210 -0
- package/dist/cpp/index.cjs +79 -0
- package/dist/cpp/index.mjs +209 -0
- package/dist/csharp/index.cjs +2 -2
- package/dist/csharp/{index.js → index.mjs} +17 -11
- package/dist/csharp/templates/framework-aspnetcore.md +205 -0
- package/dist/csharp/templates/framework-blazor.md +271 -0
- package/dist/csharp/templates/lang-csharp.md +162 -0
- package/dist/devops/docker-compose.md +111 -0
- package/dist/devops/docker-dockerfile.md +94 -0
- package/dist/devops/github-actions.md +160 -0
- package/dist/devops/gitlab-ci.md +210 -0
- package/dist/generic/lang-typescript.md +57 -0
- package/dist/generic/state-redux.md +21 -0
- package/dist/generic/state-rxjs.md +6 -0
- package/dist/generic/style-mui.md +23 -0
- package/dist/generic/style-tailwind.md +76 -0
- package/dist/generic/test-cypress.md +21 -0
- package/dist/generic/test-jest.md +20 -0
- package/dist/generic/test-playwright.md +21 -0
- package/dist/generic/test-vitest.md +131 -0
- package/dist/go/index.cjs +3 -3
- package/dist/go/{index.js → index.mjs} +18 -15
- package/dist/go/templates/lang-go.md +571 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +24 -0
- package/dist/java/index.cjs +2 -2
- package/dist/java/{index.js → index.mjs} +25 -19
- package/dist/java/templates/build-gradle.md +102 -0
- package/dist/java/templates/build-maven.md +86 -0
- package/dist/java/templates/framework-spring-boot.md +179 -0
- package/dist/java/templates/lang-java.md +78 -0
- package/dist/java/templates/lang-kotlin.md +88 -0
- package/dist/meta/magic-helix-meta.md +213 -0
- package/dist/meta/meta-debug.md +459 -0
- package/dist/meta/meta-implement.md +450 -0
- package/dist/meta/meta-roadmap.md +265 -0
- package/dist/nodejs/templates/angular-core.md +19 -0
- package/dist/nodejs/templates/lang-typescript.md +57 -0
- package/dist/nodejs/templates/nestjs-core.md +7 -0
- package/dist/nodejs/templates/react-core.md +677 -0
- package/dist/nodejs/templates/react-zustand.md +7 -0
- package/dist/nodejs/templates/state-redux.md +21 -0
- package/dist/nodejs/templates/state-rxjs.md +6 -0
- package/dist/nodejs/templates/style-primevue.md +6 -0
- package/dist/nodejs/templates/style-quasar.md +22 -0
- package/dist/nodejs/templates/style-tailwind.md +76 -0
- package/dist/nodejs/templates/test-cypress.md +21 -0
- package/dist/nodejs/templates/test-jest.md +20 -0
- package/dist/nodejs/templates/test-playwright.md +21 -0
- package/dist/nodejs/templates/test-vitest.md +131 -0
- package/dist/nodejs/templates/vue-core.md +108 -0
- package/dist/nodejs/templates/vue-pinia.md +5 -0
- package/dist/patterns/architecture/clean-architecture.md +469 -0
- package/dist/patterns/architecture/dependency-injection.md +517 -0
- package/dist/patterns/architecture/domain-driven-design.md +621 -0
- package/dist/patterns/architecture/layered-architecture.md +382 -0
- package/dist/patterns/architecture/repository-pattern.md +408 -0
- package/dist/patterns/domain-expertise/nextjs-rules.md +115 -0
- package/dist/patterns/domain-expertise/react-patterns.md +181 -0
- package/dist/patterns/domain-expertise/server-components.md +212 -0
- package/dist/patterns/domain-expertise/shadcn-ui.md +52 -0
- package/dist/patterns/domain-expertise/tailwind-patterns.md +52 -0
- package/dist/patterns/environment/container-awareness.md +17 -0
- package/dist/patterns/environment/ide-features.md +17 -0
- package/dist/patterns/environment/os-commands.md +17 -0
- package/dist/patterns/organization/heading-hierarchy.md +103 -0
- package/dist/patterns/organization/sequential-workflows.md +102 -0
- package/dist/patterns/organization/xml-rule-groups.md +64 -0
- package/dist/patterns/reasoning/agent-loop.md +151 -0
- package/dist/patterns/reasoning/confirmation-gates.md +141 -0
- package/dist/patterns/reasoning/dependency-analysis.md +132 -0
- package/dist/patterns/reasoning/one-tool-per-iteration.md +152 -0
- package/dist/patterns/reasoning/preview-before-action.md +194 -0
- package/dist/patterns/reasoning/reflection-checkpoints.md +166 -0
- package/dist/patterns/reasoning/result-verification.md +157 -0
- package/dist/patterns/reasoning/subtask-breakdown.md +131 -0
- package/dist/patterns/reasoning/thinking-tags.md +100 -0
- package/dist/patterns/role-definition/capability-declarations.md +72 -0
- package/dist/patterns/role-definition/expert-identity.md +45 -0
- package/dist/patterns/role-definition/scope-boundaries.md +61 -0
- package/dist/patterns/safety/code-safety-rules.md +17 -0
- package/dist/patterns/safety/credential-handling.md +17 -0
- package/dist/patterns/safety/destructive-warnings.md +17 -0
- package/dist/patterns/safety/refusal-messages.md +17 -0
- package/dist/patterns/tone/adaptive-tone.md +17 -0
- package/dist/patterns/tone/concise-communication.md +17 -0
- package/dist/patterns/tone/forbidden-phrases.md +17 -0
- package/dist/patterns/tool-guidelines/function-schemas.md +143 -0
- package/dist/patterns/tool-guidelines/parameter-examples.md +137 -0
- package/dist/patterns/tool-guidelines/usage-policies.md +105 -0
- package/dist/php/index.cjs +2 -2
- package/dist/php/{index.js → index.mjs} +12 -6
- package/dist/php/templates/framework-laravel.md +112 -0
- package/dist/php/templates/lang-php.md +94 -0
- package/dist/python/index.cjs +4 -4
- package/dist/python/{index.js → index.mjs} +10 -7
- package/dist/python/templates/lang-python.md +508 -0
- package/dist/ruby/index.cjs +2 -2
- package/dist/ruby/{index.js → index.mjs} +16 -10
- package/dist/ruby/templates/framework-rails.md +309 -0
- package/dist/ruby/templates/framework-sinatra.md +227 -0
- package/dist/ruby/templates/lang-ruby.md +216 -0
- package/dist/rust/index.cjs +3 -3
- package/dist/rust/{index.js → index.mjs} +24 -18
- package/dist/rust/templates/lang-rust.md +89 -0
- package/dist/swift/index.cjs +32 -0
- package/dist/swift/index.mjs +112 -0
- package/dist/swift/templates/framework-vapor.md +352 -0
- package/dist/swift/templates/lang-swift.md +291 -0
- package/package.json +31 -21
- package/dist/index.js +0 -20
- /package/dist/nodejs/{index.js → index.mjs} +0 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# GitHub Actions CI/CD Templates
|
|
2
|
+
|
|
3
|
+
## Node.js/TypeScript Pipeline
|
|
4
|
+
```yaml
|
|
5
|
+
name: Node.js CI/CD
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main, develop]
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [main]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
node-version: [18.x, 20.x]
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
22
|
+
uses: actions/setup-node@v4
|
|
23
|
+
with:
|
|
24
|
+
node-version: ${{ matrix.node-version }}
|
|
25
|
+
cache: 'npm'
|
|
26
|
+
- run: npm ci
|
|
27
|
+
- run: npm run build
|
|
28
|
+
- run: npm test
|
|
29
|
+
- run: npm run lint
|
|
30
|
+
- name: Upload coverage
|
|
31
|
+
uses: codecov/codecov-action@v4
|
|
32
|
+
if: matrix.node-version == '20.x'
|
|
33
|
+
with:
|
|
34
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
35
|
+
|
|
36
|
+
docker:
|
|
37
|
+
needs: test
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
- name: Set up Docker Buildx
|
|
43
|
+
uses: docker/setup-buildx-action@v3
|
|
44
|
+
- name: Login to DockerHub
|
|
45
|
+
uses: docker/login-action@v3
|
|
46
|
+
with:
|
|
47
|
+
username: ${{ secrets.DOCKER_USERNAME }}
|
|
48
|
+
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
49
|
+
- name: Build and push
|
|
50
|
+
uses: docker/build-push-action@v5
|
|
51
|
+
with:
|
|
52
|
+
context: .
|
|
53
|
+
push: true
|
|
54
|
+
tags: user/app:latest,user/app:${{ github.sha }}
|
|
55
|
+
cache-from: type=registry,ref=user/app:buildcache
|
|
56
|
+
cache-to: type=registry,ref=user/app:buildcache,mode=max
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Python Pipeline
|
|
60
|
+
```yaml
|
|
61
|
+
name: Python CI/CD
|
|
62
|
+
|
|
63
|
+
on: [push, pull_request]
|
|
64
|
+
|
|
65
|
+
jobs:
|
|
66
|
+
test:
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
strategy:
|
|
69
|
+
matrix:
|
|
70
|
+
python-version: ['3.10', '3.11', '3.12']
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v4
|
|
73
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
74
|
+
uses: actions/setup-python@v5
|
|
75
|
+
with:
|
|
76
|
+
python-version: ${{ matrix.python-version }}
|
|
77
|
+
- name: Install Poetry
|
|
78
|
+
uses: snok/install-poetry@v1
|
|
79
|
+
with:
|
|
80
|
+
virtualenvs-create: true
|
|
81
|
+
virtualenvs-in-project: true
|
|
82
|
+
- name: Load cached venv
|
|
83
|
+
uses: actions/cache@v4
|
|
84
|
+
with:
|
|
85
|
+
path: .venv
|
|
86
|
+
key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }}
|
|
87
|
+
- name: Install dependencies
|
|
88
|
+
run: poetry install --no-interaction
|
|
89
|
+
- name: Run tests
|
|
90
|
+
run: poetry run pytest --cov --cov-report=xml
|
|
91
|
+
- name: Run linters
|
|
92
|
+
run: |
|
|
93
|
+
poetry run ruff check .
|
|
94
|
+
poetry run mypy .
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Go Pipeline
|
|
98
|
+
```yaml
|
|
99
|
+
name: Go CI/CD
|
|
100
|
+
|
|
101
|
+
on: [push, pull_request]
|
|
102
|
+
|
|
103
|
+
jobs:
|
|
104
|
+
test:
|
|
105
|
+
runs-on: ubuntu-latest
|
|
106
|
+
steps:
|
|
107
|
+
- uses: actions/checkout@v4
|
|
108
|
+
- name: Set up Go
|
|
109
|
+
uses: actions/setup-go@v5
|
|
110
|
+
with:
|
|
111
|
+
go-version: '1.21'
|
|
112
|
+
cache: true
|
|
113
|
+
- name: Verify dependencies
|
|
114
|
+
run: go mod verify
|
|
115
|
+
- name: Build
|
|
116
|
+
run: go build -v ./...
|
|
117
|
+
- name: Run tests
|
|
118
|
+
run: go test -v -race -coverprofile=coverage.txt ./...
|
|
119
|
+
- name: Lint
|
|
120
|
+
uses: golangci/golangci-lint-action@v4
|
|
121
|
+
with:
|
|
122
|
+
version: latest
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Rust Pipeline
|
|
126
|
+
```yaml
|
|
127
|
+
name: Rust CI/CD
|
|
128
|
+
|
|
129
|
+
on: [push, pull_request]
|
|
130
|
+
|
|
131
|
+
jobs:
|
|
132
|
+
test:
|
|
133
|
+
runs-on: ubuntu-latest
|
|
134
|
+
steps:
|
|
135
|
+
- uses: actions/checkout@v4
|
|
136
|
+
- name: Install Rust
|
|
137
|
+
uses: dtolnay/rust-toolchain@stable
|
|
138
|
+
with:
|
|
139
|
+
components: rustfmt, clippy
|
|
140
|
+
- name: Cache cargo registry
|
|
141
|
+
uses: actions/cache@v4
|
|
142
|
+
with:
|
|
143
|
+
path: ~/.cargo/registry
|
|
144
|
+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
|
145
|
+
- name: Cache cargo index
|
|
146
|
+
uses: actions/cache@v4
|
|
147
|
+
with:
|
|
148
|
+
path: ~/.cargo/git
|
|
149
|
+
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
|
|
150
|
+
- name: Cache target
|
|
151
|
+
uses: actions/cache@v4
|
|
152
|
+
with:
|
|
153
|
+
path: target
|
|
154
|
+
key: ${{ runner.os }}-target-${{ hashFiles('**/Cargo.lock') }}
|
|
155
|
+
- name: Check formatting
|
|
156
|
+
run: cargo fmt -- --check
|
|
157
|
+
- name: Run clippy
|
|
158
|
+
run: cargo clippy -- -D warnings
|
|
159
|
+
- name: Run tests
|
|
160
|
+
run: cargo test --verbose
|
|
161
|
+
- name: Build release
|
|
162
|
+
run: cargo build --release --verbose
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Java/Maven Pipeline
|
|
166
|
+
```yaml
|
|
167
|
+
name: Java CI/CD
|
|
168
|
+
|
|
169
|
+
on: [push, pull_request]
|
|
170
|
+
|
|
171
|
+
jobs:
|
|
172
|
+
build:
|
|
173
|
+
runs-on: ubuntu-latest
|
|
174
|
+
steps:
|
|
175
|
+
- uses: actions/checkout@v4
|
|
176
|
+
- name: Set up JDK 21
|
|
177
|
+
uses: actions/setup-java@v4
|
|
178
|
+
with:
|
|
179
|
+
java-version: '21'
|
|
180
|
+
distribution: 'temurin'
|
|
181
|
+
cache: 'maven'
|
|
182
|
+
- name: Build with Maven
|
|
183
|
+
run: mvn -B package --file pom.xml
|
|
184
|
+
- name: Run tests
|
|
185
|
+
run: mvn test
|
|
186
|
+
- name: Generate coverage report
|
|
187
|
+
run: mvn jacoco:report
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Multi-Platform Docker Build
|
|
191
|
+
```yaml
|
|
192
|
+
name: Docker Multi-Arch
|
|
193
|
+
|
|
194
|
+
on:
|
|
195
|
+
push:
|
|
196
|
+
tags: ['v*']
|
|
197
|
+
|
|
198
|
+
jobs:
|
|
199
|
+
build:
|
|
200
|
+
runs-on: ubuntu-latest
|
|
201
|
+
steps:
|
|
202
|
+
- uses: actions/checkout@v4
|
|
203
|
+
- name: Set up QEMU
|
|
204
|
+
uses: docker/setup-qemu-action@v3
|
|
205
|
+
- name: Set up Docker Buildx
|
|
206
|
+
uses: docker/setup-buildx-action@v3
|
|
207
|
+
- name: Login to GHCR
|
|
208
|
+
uses: docker/login-action@v3
|
|
209
|
+
with:
|
|
210
|
+
registry: ghcr.io
|
|
211
|
+
username: ${{ github.actor }}
|
|
212
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
213
|
+
- name: Extract metadata
|
|
214
|
+
id: meta
|
|
215
|
+
uses: docker/metadata-action@v5
|
|
216
|
+
with:
|
|
217
|
+
images: ghcr.io/${{ github.repository }}
|
|
218
|
+
tags: |
|
|
219
|
+
type=ref,event=branch
|
|
220
|
+
type=semver,pattern={{version}}
|
|
221
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
222
|
+
- name: Build and push
|
|
223
|
+
uses: docker/build-push-action@v5
|
|
224
|
+
with:
|
|
225
|
+
context: .
|
|
226
|
+
platforms: linux/amd64,linux/arm64
|
|
227
|
+
push: true
|
|
228
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
229
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Security Scanning
|
|
233
|
+
```yaml
|
|
234
|
+
name: Security Scan
|
|
235
|
+
|
|
236
|
+
on:
|
|
237
|
+
push:
|
|
238
|
+
branches: [main]
|
|
239
|
+
schedule:
|
|
240
|
+
- cron: '0 0 * * 0' # Weekly
|
|
241
|
+
|
|
242
|
+
jobs:
|
|
243
|
+
scan:
|
|
244
|
+
runs-on: ubuntu-latest
|
|
245
|
+
steps:
|
|
246
|
+
- uses: actions/checkout@v4
|
|
247
|
+
- name: Run Trivy vulnerability scanner
|
|
248
|
+
uses: aquasecurity/trivy-action@master
|
|
249
|
+
with:
|
|
250
|
+
scan-type: 'fs'
|
|
251
|
+
scan-ref: '.'
|
|
252
|
+
format: 'sarif'
|
|
253
|
+
output: 'trivy-results.sarif'
|
|
254
|
+
- name: Upload results to GitHub Security
|
|
255
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
256
|
+
with:
|
|
257
|
+
sarif_file: 'trivy-results.sarif'
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Best Practices
|
|
261
|
+
1. **Caching**: Use `actions/cache` for dependencies (npm, pip, cargo, maven)
|
|
262
|
+
2. **Matrix Builds**: Test against multiple language versions
|
|
263
|
+
3. **Secrets**: Store credentials in GitHub Secrets, never in code
|
|
264
|
+
4. **Branch Protection**: Require CI to pass before merging
|
|
265
|
+
5. **Parallel Jobs**: Use `needs` to orchestrate job dependencies
|
|
266
|
+
6. **Docker Layer Caching**: Use registry cache or buildx cache backends
|
|
267
|
+
7. **Security Scanning**: Integrate Trivy, Snyk, or CodeQL
|
|
268
|
+
8. **Artifact Storage**: Upload test reports and binaries with `actions/upload-artifact`
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# GitLab CI/CD Templates
|
|
2
|
+
|
|
3
|
+
## Node.js/TypeScript Pipeline
|
|
4
|
+
```yaml
|
|
5
|
+
image: node:20-alpine
|
|
6
|
+
|
|
7
|
+
stages:
|
|
8
|
+
- build
|
|
9
|
+
- test
|
|
10
|
+
- docker
|
|
11
|
+
- deploy
|
|
12
|
+
|
|
13
|
+
cache:
|
|
14
|
+
key:
|
|
15
|
+
files:
|
|
16
|
+
- package-lock.json
|
|
17
|
+
paths:
|
|
18
|
+
- node_modules/
|
|
19
|
+
- .npm/
|
|
20
|
+
|
|
21
|
+
variables:
|
|
22
|
+
npm_config_cache: "$CI_PROJECT_DIR/.npm"
|
|
23
|
+
|
|
24
|
+
build:
|
|
25
|
+
stage: build
|
|
26
|
+
script:
|
|
27
|
+
- npm ci
|
|
28
|
+
- npm run build
|
|
29
|
+
artifacts:
|
|
30
|
+
paths:
|
|
31
|
+
- dist/
|
|
32
|
+
expire_in: 1 hour
|
|
33
|
+
|
|
34
|
+
test:
|
|
35
|
+
stage: test
|
|
36
|
+
coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
|
|
37
|
+
script:
|
|
38
|
+
- npm ci
|
|
39
|
+
- npm test -- --coverage
|
|
40
|
+
artifacts:
|
|
41
|
+
reports:
|
|
42
|
+
coverage_report:
|
|
43
|
+
coverage_format: cobertura
|
|
44
|
+
path: coverage/cobertura-coverage.xml
|
|
45
|
+
junit: junit.xml
|
|
46
|
+
|
|
47
|
+
lint:
|
|
48
|
+
stage: test
|
|
49
|
+
script:
|
|
50
|
+
- npm ci
|
|
51
|
+
- npm run lint
|
|
52
|
+
|
|
53
|
+
docker-build:
|
|
54
|
+
stage: docker
|
|
55
|
+
image: docker:latest
|
|
56
|
+
services:
|
|
57
|
+
- docker:dind
|
|
58
|
+
before_script:
|
|
59
|
+
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
|
60
|
+
script:
|
|
61
|
+
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
|
|
62
|
+
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:latest
|
|
63
|
+
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
|
|
64
|
+
- docker push $CI_REGISTRY_IMAGE:latest
|
|
65
|
+
only:
|
|
66
|
+
- main
|
|
67
|
+
|
|
68
|
+
deploy-production:
|
|
69
|
+
stage: deploy
|
|
70
|
+
image: alpine/kubectl:latest
|
|
71
|
+
script:
|
|
72
|
+
- kubectl config set-cluster k8s --server="$KUBE_URL" --insecure-skip-tls-verify=true
|
|
73
|
+
- kubectl config set-credentials admin --token="$KUBE_TOKEN"
|
|
74
|
+
- kubectl config set-context default --cluster=k8s --user=admin
|
|
75
|
+
- kubectl config use-context default
|
|
76
|
+
- kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n production
|
|
77
|
+
environment:
|
|
78
|
+
name: production
|
|
79
|
+
url: https://app.example.com
|
|
80
|
+
only:
|
|
81
|
+
- main
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Python Pipeline
|
|
85
|
+
```yaml
|
|
86
|
+
image: python:3.12-slim
|
|
87
|
+
|
|
88
|
+
stages:
|
|
89
|
+
- test
|
|
90
|
+
- build
|
|
91
|
+
- deploy
|
|
92
|
+
|
|
93
|
+
variables:
|
|
94
|
+
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
|
95
|
+
|
|
96
|
+
cache:
|
|
97
|
+
paths:
|
|
98
|
+
- .cache/pip
|
|
99
|
+
- .venv/
|
|
100
|
+
|
|
101
|
+
before_script:
|
|
102
|
+
- pip install poetry
|
|
103
|
+
- poetry config virtualenvs.in-project true
|
|
104
|
+
- poetry install
|
|
105
|
+
|
|
106
|
+
test:
|
|
107
|
+
stage: test
|
|
108
|
+
script:
|
|
109
|
+
- poetry run pytest --cov --cov-report=xml --cov-report=term
|
|
110
|
+
- poetry run ruff check .
|
|
111
|
+
- poetry run mypy .
|
|
112
|
+
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
|
|
113
|
+
artifacts:
|
|
114
|
+
reports:
|
|
115
|
+
coverage_report:
|
|
116
|
+
coverage_format: cobertura
|
|
117
|
+
path: coverage.xml
|
|
118
|
+
|
|
119
|
+
docker:
|
|
120
|
+
stage: build
|
|
121
|
+
image: docker:latest
|
|
122
|
+
services:
|
|
123
|
+
- docker:dind
|
|
124
|
+
script:
|
|
125
|
+
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
|
|
126
|
+
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
|
|
127
|
+
only:
|
|
128
|
+
- main
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Go Pipeline
|
|
132
|
+
```yaml
|
|
133
|
+
image: golang:1.21
|
|
134
|
+
|
|
135
|
+
stages:
|
|
136
|
+
- test
|
|
137
|
+
- build
|
|
138
|
+
|
|
139
|
+
variables:
|
|
140
|
+
GOPATH: $CI_PROJECT_DIR/.go
|
|
141
|
+
|
|
142
|
+
cache:
|
|
143
|
+
paths:
|
|
144
|
+
- .go/pkg/mod/
|
|
145
|
+
|
|
146
|
+
before_script:
|
|
147
|
+
- mkdir -p .go
|
|
148
|
+
- go mod download
|
|
149
|
+
|
|
150
|
+
test:
|
|
151
|
+
stage: test
|
|
152
|
+
script:
|
|
153
|
+
- go fmt $(go list ./... | grep -v /vendor/)
|
|
154
|
+
- go vet $(go list ./... | grep -v /vendor/)
|
|
155
|
+
- go test -race -coverprofile=coverage.txt -covermode=atomic ./...
|
|
156
|
+
coverage: '/coverage: \d+\.\d+% of statements/'
|
|
157
|
+
artifacts:
|
|
158
|
+
reports:
|
|
159
|
+
coverage_report:
|
|
160
|
+
coverage_format: cobertura
|
|
161
|
+
path: coverage.xml
|
|
162
|
+
|
|
163
|
+
build:
|
|
164
|
+
stage: build
|
|
165
|
+
script:
|
|
166
|
+
- CGO_ENABLED=0 go build -ldflags="-s -w" -o app
|
|
167
|
+
artifacts:
|
|
168
|
+
paths:
|
|
169
|
+
- app
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Rust Pipeline
|
|
173
|
+
```yaml
|
|
174
|
+
image: rust:1.75
|
|
175
|
+
|
|
176
|
+
stages:
|
|
177
|
+
- test
|
|
178
|
+
- build
|
|
179
|
+
|
|
180
|
+
variables:
|
|
181
|
+
CARGO_HOME: $CI_PROJECT_DIR/.cargo
|
|
182
|
+
|
|
183
|
+
cache:
|
|
184
|
+
paths:
|
|
185
|
+
- .cargo/
|
|
186
|
+
- target/
|
|
187
|
+
|
|
188
|
+
test:
|
|
189
|
+
stage: test
|
|
190
|
+
script:
|
|
191
|
+
- rustc --version && cargo --version
|
|
192
|
+
- cargo fmt -- --check
|
|
193
|
+
- cargo clippy -- -D warnings
|
|
194
|
+
- cargo test --verbose
|
|
195
|
+
|
|
196
|
+
build:
|
|
197
|
+
stage: build
|
|
198
|
+
script:
|
|
199
|
+
- cargo build --release
|
|
200
|
+
artifacts:
|
|
201
|
+
paths:
|
|
202
|
+
- target/release/app
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Java/Maven Pipeline
|
|
206
|
+
```yaml
|
|
207
|
+
image: maven:3.9-eclipse-temurin-21
|
|
208
|
+
|
|
209
|
+
stages:
|
|
210
|
+
- build
|
|
211
|
+
- test
|
|
212
|
+
- package
|
|
213
|
+
|
|
214
|
+
variables:
|
|
215
|
+
MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
|
|
216
|
+
|
|
217
|
+
cache:
|
|
218
|
+
paths:
|
|
219
|
+
- .m2/repository
|
|
220
|
+
|
|
221
|
+
build:
|
|
222
|
+
stage: build
|
|
223
|
+
script:
|
|
224
|
+
- mvn compile
|
|
225
|
+
|
|
226
|
+
test:
|
|
227
|
+
stage: test
|
|
228
|
+
script:
|
|
229
|
+
- mvn test
|
|
230
|
+
- mvn jacoco:report
|
|
231
|
+
coverage: '/Total.*?([0-9]{1,3})%/'
|
|
232
|
+
artifacts:
|
|
233
|
+
reports:
|
|
234
|
+
junit: target/surefire-reports/TEST-*.xml
|
|
235
|
+
|
|
236
|
+
package:
|
|
237
|
+
stage: package
|
|
238
|
+
script:
|
|
239
|
+
- mvn package -DskipTests
|
|
240
|
+
artifacts:
|
|
241
|
+
paths:
|
|
242
|
+
- target/*.jar
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Multi-Stage with Environments
|
|
246
|
+
```yaml
|
|
247
|
+
stages:
|
|
248
|
+
- build
|
|
249
|
+
- test
|
|
250
|
+
- staging
|
|
251
|
+
- production
|
|
252
|
+
|
|
253
|
+
build:
|
|
254
|
+
stage: build
|
|
255
|
+
script:
|
|
256
|
+
- npm ci
|
|
257
|
+
- npm run build
|
|
258
|
+
artifacts:
|
|
259
|
+
paths:
|
|
260
|
+
- dist/
|
|
261
|
+
|
|
262
|
+
test:
|
|
263
|
+
stage: test
|
|
264
|
+
script:
|
|
265
|
+
- npm test
|
|
266
|
+
|
|
267
|
+
deploy-staging:
|
|
268
|
+
stage: staging
|
|
269
|
+
script:
|
|
270
|
+
- echo "Deploying to staging"
|
|
271
|
+
- kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n staging
|
|
272
|
+
environment:
|
|
273
|
+
name: staging
|
|
274
|
+
url: https://staging.example.com
|
|
275
|
+
only:
|
|
276
|
+
- develop
|
|
277
|
+
|
|
278
|
+
deploy-production:
|
|
279
|
+
stage: production
|
|
280
|
+
script:
|
|
281
|
+
- echo "Deploying to production"
|
|
282
|
+
- kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n production
|
|
283
|
+
environment:
|
|
284
|
+
name: production
|
|
285
|
+
url: https://app.example.com
|
|
286
|
+
when: manual
|
|
287
|
+
only:
|
|
288
|
+
- main
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Docker with Buildx (Multi-arch)
|
|
292
|
+
```yaml
|
|
293
|
+
docker-multiarch:
|
|
294
|
+
stage: build
|
|
295
|
+
image: docker:latest
|
|
296
|
+
services:
|
|
297
|
+
- docker:dind
|
|
298
|
+
before_script:
|
|
299
|
+
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
|
300
|
+
- docker buildx create --use --name multiarch
|
|
301
|
+
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
|
302
|
+
script:
|
|
303
|
+
- docker buildx build --platform linux/amd64,linux/arm64 -t $CI_REGISTRY_IMAGE:latest --push .
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Security Scanning
|
|
307
|
+
```yaml
|
|
308
|
+
include:
|
|
309
|
+
- template: Security/SAST.gitlab-ci.yml
|
|
310
|
+
- template: Security/Dependency-Scanning.gitlab-ci.yml
|
|
311
|
+
- template: Security/Container-Scanning.gitlab-ci.yml
|
|
312
|
+
|
|
313
|
+
container_scanning:
|
|
314
|
+
variables:
|
|
315
|
+
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
|
|
316
|
+
dependencies:
|
|
317
|
+
- docker-build
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Best Practices
|
|
321
|
+
1. **Caching**: Cache dependencies (`node_modules/`, `.m2/`, `.cargo/`)
|
|
322
|
+
2. **Artifacts**: Pass build outputs between stages
|
|
323
|
+
3. **Environments**: Use GitLab environments for deployment tracking
|
|
324
|
+
4. **Manual Gates**: Use `when: manual` for production deployments
|
|
325
|
+
5. **Templates**: Use `include:` to reuse common configurations
|
|
326
|
+
6. **Variables**: Store secrets in GitLab CI/CD Variables (masked & protected)
|
|
327
|
+
7. **Docker Layer Caching**: Use `DOCKER_BUILDKIT=1` for faster builds
|
|
328
|
+
8. **Coverage**: Use `coverage:` regex to display coverage in merge requests
|
|
329
|
+
9. **Resource Groups**: Prevent concurrent deployments to the same environment
|
|
330
|
+
10. **Rules**: Use `rules:` instead of `only:`/`except:` for modern syntax
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Docker Multi-Stage Build Best Practices
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Multi-stage builds reduce image size and improve security by separating build-time and runtime dependencies.
|
|
5
|
+
|
|
6
|
+
## Basic Pattern
|
|
7
|
+
```dockerfile
|
|
8
|
+
# Stage 1: Build
|
|
9
|
+
FROM builder-image AS builder
|
|
10
|
+
WORKDIR /build
|
|
11
|
+
COPY source files
|
|
12
|
+
RUN build commands
|
|
13
|
+
|
|
14
|
+
# Stage 2: Runtime
|
|
15
|
+
FROM runtime-image
|
|
16
|
+
WORKDIR /app
|
|
17
|
+
COPY --from=builder /build/artifacts .
|
|
18
|
+
CMD ["run", "app"]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Language-Specific Optimizations
|
|
22
|
+
|
|
23
|
+
### Go
|
|
24
|
+
```dockerfile
|
|
25
|
+
FROM golang:1.21-alpine AS builder
|
|
26
|
+
WORKDIR /build
|
|
27
|
+
COPY go.mod go.sum ./
|
|
28
|
+
RUN go mod download
|
|
29
|
+
COPY . .
|
|
30
|
+
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o app
|
|
31
|
+
|
|
32
|
+
FROM scratch
|
|
33
|
+
COPY --from=builder /build/app /app
|
|
34
|
+
ENTRYPOINT ["/app"]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Rust
|
|
38
|
+
```dockerfile
|
|
39
|
+
FROM rust:1.75-alpine AS builder
|
|
40
|
+
WORKDIR /build
|
|
41
|
+
RUN apk add --no-cache musl-dev
|
|
42
|
+
COPY Cargo.toml Cargo.lock ./
|
|
43
|
+
RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release && rm -rf src
|
|
44
|
+
COPY src ./src
|
|
45
|
+
RUN touch src/main.rs && cargo build --release
|
|
46
|
+
|
|
47
|
+
FROM alpine:latest
|
|
48
|
+
RUN apk add --no-cache ca-certificates
|
|
49
|
+
COPY --from=builder /build/target/release/app /app
|
|
50
|
+
CMD ["/app"]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Node.js
|
|
54
|
+
```dockerfile
|
|
55
|
+
FROM node:20-alpine AS builder
|
|
56
|
+
WORKDIR /build
|
|
57
|
+
COPY package*.json ./
|
|
58
|
+
RUN npm ci --only=production
|
|
59
|
+
|
|
60
|
+
FROM node:20-alpine
|
|
61
|
+
WORKDIR /app
|
|
62
|
+
COPY --from=builder /build/node_modules ./node_modules
|
|
63
|
+
COPY . .
|
|
64
|
+
CMD ["node", "index.js"]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Java/Spring Boot
|
|
68
|
+
```dockerfile
|
|
69
|
+
FROM maven:3.9-eclipse-temurin-21 AS builder
|
|
70
|
+
WORKDIR /build
|
|
71
|
+
COPY pom.xml .
|
|
72
|
+
RUN mvn dependency:go-offline
|
|
73
|
+
COPY src ./src
|
|
74
|
+
RUN mvn package -DskipTests
|
|
75
|
+
|
|
76
|
+
FROM eclipse-temurin:21-jre-alpine
|
|
77
|
+
WORKDIR /app
|
|
78
|
+
COPY --from=builder /build/target/*.jar app.jar
|
|
79
|
+
ENTRYPOINT ["java", "-jar", "app.jar"]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Python
|
|
83
|
+
```dockerfile
|
|
84
|
+
FROM python:3.12-slim AS builder
|
|
85
|
+
WORKDIR /build
|
|
86
|
+
RUN pip install --no-cache-dir poetry
|
|
87
|
+
COPY pyproject.toml poetry.lock ./
|
|
88
|
+
RUN poetry export -f requirements.txt -o requirements.txt --without-hashes
|
|
89
|
+
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt
|
|
90
|
+
|
|
91
|
+
FROM python:3.12-slim
|
|
92
|
+
WORKDIR /app
|
|
93
|
+
COPY --from=builder /wheels /wheels
|
|
94
|
+
RUN pip install --no-cache-dir /wheels/*
|
|
95
|
+
COPY . .
|
|
96
|
+
CMD ["python", "main.py"]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Security Hardening
|
|
100
|
+
- Use specific image tags, not `latest`
|
|
101
|
+
- Run as non-root user: `USER 1000:1000`
|
|
102
|
+
- Scan images: `docker scout cves image:tag`
|
|
103
|
+
- Use distroless or alpine base images
|
|
104
|
+
- Multi-platform builds: `docker buildx build --platform linux/amd64,linux/arm64`
|
|
105
|
+
|
|
106
|
+
## .dockerignore Template
|
|
107
|
+
```
|
|
108
|
+
node_modules
|
|
109
|
+
.git
|
|
110
|
+
.env
|
|
111
|
+
*.log
|
|
112
|
+
dist
|
|
113
|
+
coverage
|
|
114
|
+
.vscode
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Build Optimization
|
|
118
|
+
- Layer caching: COPY dependency files before source code
|
|
119
|
+
- Parallel builds: `RUN cmd1 & cmd2 & wait`
|
|
120
|
+
- Build contexts: Use `.dockerignore` to exclude unnecessary files
|