omgkit 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugin/skills/SKILL_STANDARDS.md +743 -0
- package/plugin/skills/databases/mongodb/SKILL.md +797 -28
- package/plugin/skills/databases/postgresql/SKILL.md +494 -18
- package/plugin/skills/databases/prisma/SKILL.md +776 -30
- package/plugin/skills/databases/redis/SKILL.md +885 -25
- package/plugin/skills/devops/aws/SKILL.md +686 -28
- package/plugin/skills/devops/docker/SKILL.md +466 -18
- package/plugin/skills/devops/github-actions/SKILL.md +684 -29
- package/plugin/skills/devops/kubernetes/SKILL.md +621 -24
- package/plugin/skills/frameworks/django/SKILL.md +920 -20
- package/plugin/skills/frameworks/express/SKILL.md +1361 -35
- package/plugin/skills/frameworks/fastapi/SKILL.md +1260 -33
- package/plugin/skills/frameworks/laravel/SKILL.md +1244 -31
- package/plugin/skills/frameworks/nestjs/SKILL.md +1005 -26
- package/plugin/skills/frameworks/nextjs/SKILL.md +407 -44
- package/plugin/skills/frameworks/rails/SKILL.md +594 -28
- package/plugin/skills/frameworks/react/SKILL.md +1006 -32
- package/plugin/skills/frameworks/spring/SKILL.md +528 -35
- package/plugin/skills/frameworks/vue/SKILL.md +1296 -27
- package/plugin/skills/frontend/accessibility/SKILL.md +1108 -34
- package/plugin/skills/frontend/frontend-design/SKILL.md +1304 -26
- package/plugin/skills/frontend/responsive/SKILL.md +847 -21
- package/plugin/skills/frontend/shadcn-ui/SKILL.md +976 -38
- package/plugin/skills/frontend/tailwindcss/SKILL.md +831 -35
- package/plugin/skills/frontend/threejs/SKILL.md +1298 -29
- package/plugin/skills/languages/javascript/SKILL.md +935 -31
- package/plugin/skills/languages/python/SKILL.md +489 -25
- package/plugin/skills/languages/typescript/SKILL.md +379 -30
- package/plugin/skills/methodology/brainstorming/SKILL.md +597 -23
- package/plugin/skills/methodology/defense-in-depth/SKILL.md +832 -34
- package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +665 -31
- package/plugin/skills/methodology/executing-plans/SKILL.md +556 -24
- package/plugin/skills/methodology/finishing-development-branch/SKILL.md +595 -25
- package/plugin/skills/methodology/problem-solving/SKILL.md +429 -61
- package/plugin/skills/methodology/receiving-code-review/SKILL.md +536 -24
- package/plugin/skills/methodology/requesting-code-review/SKILL.md +632 -21
- package/plugin/skills/methodology/root-cause-tracing/SKILL.md +641 -30
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +262 -3
- package/plugin/skills/methodology/systematic-debugging/SKILL.md +571 -32
- package/plugin/skills/methodology/test-driven-development/SKILL.md +779 -24
- package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +691 -29
- package/plugin/skills/methodology/token-optimization/SKILL.md +598 -29
- package/plugin/skills/methodology/verification-before-completion/SKILL.md +543 -22
- package/plugin/skills/methodology/writing-plans/SKILL.md +590 -18
- package/plugin/skills/omega/omega-architecture/SKILL.md +838 -39
- package/plugin/skills/omega/omega-coding/SKILL.md +636 -39
- package/plugin/skills/omega/omega-sprint/SKILL.md +855 -48
- package/plugin/skills/omega/omega-testing/SKILL.md +940 -41
- package/plugin/skills/omega/omega-thinking/SKILL.md +703 -50
- package/plugin/skills/security/better-auth/SKILL.md +1065 -28
- package/plugin/skills/security/oauth/SKILL.md +968 -31
- package/plugin/skills/security/owasp/SKILL.md +894 -33
- package/plugin/skills/testing/playwright/SKILL.md +764 -38
- package/plugin/skills/testing/pytest/SKILL.md +873 -36
- package/plugin/skills/testing/vitest/SKILL.md +980 -35
|
@@ -1,63 +1,718 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github-actions
|
|
3
|
-
description: GitHub Actions CI/CD
|
|
3
|
+
description: GitHub Actions CI/CD with workflows, reusable actions, matrix builds, and deployment automation
|
|
4
|
+
category: devops
|
|
5
|
+
triggers:
|
|
6
|
+
- github actions
|
|
7
|
+
- github workflow
|
|
8
|
+
- ci cd
|
|
9
|
+
- github ci
|
|
10
|
+
- actions
|
|
11
|
+
- workflow
|
|
12
|
+
- github pipeline
|
|
4
13
|
---
|
|
5
14
|
|
|
6
|
-
# GitHub Actions
|
|
15
|
+
# GitHub Actions
|
|
16
|
+
|
|
17
|
+
Enterprise-grade **GitHub Actions CI/CD** following industry best practices. This skill covers workflow configuration, reusable actions, matrix builds, deployment strategies, secrets management, and production-ready automation patterns used by top engineering teams.
|
|
18
|
+
|
|
19
|
+
## Purpose
|
|
20
|
+
|
|
21
|
+
Build robust CI/CD pipelines with GitHub Actions:
|
|
22
|
+
|
|
23
|
+
- Configure comprehensive CI workflows
|
|
24
|
+
- Create reusable composite actions
|
|
25
|
+
- Implement matrix builds for multiple environments
|
|
26
|
+
- Deploy to various platforms
|
|
27
|
+
- Manage secrets and environments
|
|
28
|
+
- Optimize workflow performance
|
|
29
|
+
- Implement security scanning
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
### 1. Complete CI Workflow
|
|
7
34
|
|
|
8
|
-
## CI Workflow
|
|
9
35
|
```yaml
|
|
36
|
+
# .github/workflows/ci.yml
|
|
10
37
|
name: CI
|
|
11
38
|
|
|
12
39
|
on:
|
|
13
40
|
push:
|
|
14
|
-
branches: [main]
|
|
41
|
+
branches: [main, develop]
|
|
15
42
|
pull_request:
|
|
43
|
+
branches: [main, develop]
|
|
44
|
+
|
|
45
|
+
concurrency:
|
|
46
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
47
|
+
cancel-in-progress: true
|
|
48
|
+
|
|
49
|
+
env:
|
|
50
|
+
NODE_VERSION: '20'
|
|
51
|
+
PNPM_VERSION: '8'
|
|
52
|
+
|
|
53
|
+
jobs:
|
|
54
|
+
lint:
|
|
55
|
+
name: Lint
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- name: Checkout
|
|
59
|
+
uses: actions/checkout@v4
|
|
60
|
+
|
|
61
|
+
- name: Setup pnpm
|
|
62
|
+
uses: pnpm/action-setup@v2
|
|
63
|
+
with:
|
|
64
|
+
version: ${{ env.PNPM_VERSION }}
|
|
65
|
+
|
|
66
|
+
- name: Setup Node.js
|
|
67
|
+
uses: actions/setup-node@v4
|
|
68
|
+
with:
|
|
69
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
70
|
+
cache: 'pnpm'
|
|
71
|
+
|
|
72
|
+
- name: Install dependencies
|
|
73
|
+
run: pnpm install --frozen-lockfile
|
|
74
|
+
|
|
75
|
+
- name: Run ESLint
|
|
76
|
+
run: pnpm lint
|
|
77
|
+
|
|
78
|
+
- name: Run Prettier
|
|
79
|
+
run: pnpm format:check
|
|
80
|
+
|
|
81
|
+
- name: TypeScript type check
|
|
82
|
+
run: pnpm type-check
|
|
83
|
+
|
|
84
|
+
test:
|
|
85
|
+
name: Test
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
needs: lint
|
|
88
|
+
services:
|
|
89
|
+
postgres:
|
|
90
|
+
image: postgres:15
|
|
91
|
+
env:
|
|
92
|
+
POSTGRES_USER: test
|
|
93
|
+
POSTGRES_PASSWORD: test
|
|
94
|
+
POSTGRES_DB: testdb
|
|
95
|
+
ports:
|
|
96
|
+
- 5432:5432
|
|
97
|
+
options: >-
|
|
98
|
+
--health-cmd pg_isready
|
|
99
|
+
--health-interval 10s
|
|
100
|
+
--health-timeout 5s
|
|
101
|
+
--health-retries 5
|
|
102
|
+
|
|
103
|
+
redis:
|
|
104
|
+
image: redis:7
|
|
105
|
+
ports:
|
|
106
|
+
- 6379:6379
|
|
107
|
+
options: >-
|
|
108
|
+
--health-cmd "redis-cli ping"
|
|
109
|
+
--health-interval 10s
|
|
110
|
+
--health-timeout 5s
|
|
111
|
+
--health-retries 5
|
|
112
|
+
|
|
113
|
+
steps:
|
|
114
|
+
- name: Checkout
|
|
115
|
+
uses: actions/checkout@v4
|
|
116
|
+
|
|
117
|
+
- name: Setup pnpm
|
|
118
|
+
uses: pnpm/action-setup@v2
|
|
119
|
+
with:
|
|
120
|
+
version: ${{ env.PNPM_VERSION }}
|
|
121
|
+
|
|
122
|
+
- name: Setup Node.js
|
|
123
|
+
uses: actions/setup-node@v4
|
|
124
|
+
with:
|
|
125
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
126
|
+
cache: 'pnpm'
|
|
127
|
+
|
|
128
|
+
- name: Install dependencies
|
|
129
|
+
run: pnpm install --frozen-lockfile
|
|
130
|
+
|
|
131
|
+
- name: Run database migrations
|
|
132
|
+
run: pnpm db:migrate
|
|
133
|
+
env:
|
|
134
|
+
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
|
|
135
|
+
|
|
136
|
+
- name: Run tests
|
|
137
|
+
run: pnpm test:coverage
|
|
138
|
+
env:
|
|
139
|
+
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
|
|
140
|
+
REDIS_URL: redis://localhost:6379
|
|
141
|
+
|
|
142
|
+
- name: Upload coverage
|
|
143
|
+
uses: codecov/codecov-action@v3
|
|
144
|
+
with:
|
|
145
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
146
|
+
files: ./coverage/lcov.info
|
|
147
|
+
fail_ci_if_error: true
|
|
148
|
+
|
|
149
|
+
build:
|
|
150
|
+
name: Build
|
|
151
|
+
runs-on: ubuntu-latest
|
|
152
|
+
needs: test
|
|
153
|
+
steps:
|
|
154
|
+
- name: Checkout
|
|
155
|
+
uses: actions/checkout@v4
|
|
156
|
+
|
|
157
|
+
- name: Setup pnpm
|
|
158
|
+
uses: pnpm/action-setup@v2
|
|
159
|
+
with:
|
|
160
|
+
version: ${{ env.PNPM_VERSION }}
|
|
161
|
+
|
|
162
|
+
- name: Setup Node.js
|
|
163
|
+
uses: actions/setup-node@v4
|
|
164
|
+
with:
|
|
165
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
166
|
+
cache: 'pnpm'
|
|
167
|
+
|
|
168
|
+
- name: Install dependencies
|
|
169
|
+
run: pnpm install --frozen-lockfile
|
|
170
|
+
|
|
171
|
+
- name: Build application
|
|
172
|
+
run: pnpm build
|
|
173
|
+
|
|
174
|
+
- name: Upload build artifacts
|
|
175
|
+
uses: actions/upload-artifact@v4
|
|
176
|
+
with:
|
|
177
|
+
name: build
|
|
178
|
+
path: dist/
|
|
179
|
+
retention-days: 7
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 2. Matrix Build Strategy
|
|
183
|
+
|
|
184
|
+
```yaml
|
|
185
|
+
# .github/workflows/matrix.yml
|
|
186
|
+
name: Matrix Build
|
|
187
|
+
|
|
188
|
+
on:
|
|
189
|
+
push:
|
|
16
190
|
branches: [main]
|
|
191
|
+
pull_request:
|
|
17
192
|
|
|
18
193
|
jobs:
|
|
19
194
|
test:
|
|
195
|
+
name: Test (${{ matrix.os }}, Node ${{ matrix.node }})
|
|
196
|
+
runs-on: ${{ matrix.os }}
|
|
197
|
+
strategy:
|
|
198
|
+
fail-fast: false
|
|
199
|
+
matrix:
|
|
200
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
201
|
+
node: [18, 20, 22]
|
|
202
|
+
exclude:
|
|
203
|
+
- os: windows-latest
|
|
204
|
+
node: 18
|
|
205
|
+
include:
|
|
206
|
+
- os: ubuntu-latest
|
|
207
|
+
node: 20
|
|
208
|
+
coverage: true
|
|
209
|
+
|
|
210
|
+
steps:
|
|
211
|
+
- name: Checkout
|
|
212
|
+
uses: actions/checkout@v4
|
|
213
|
+
|
|
214
|
+
- name: Setup Node.js ${{ matrix.node }}
|
|
215
|
+
uses: actions/setup-node@v4
|
|
216
|
+
with:
|
|
217
|
+
node-version: ${{ matrix.node }}
|
|
218
|
+
cache: 'npm'
|
|
219
|
+
|
|
220
|
+
- name: Install dependencies
|
|
221
|
+
run: npm ci
|
|
222
|
+
|
|
223
|
+
- name: Run tests
|
|
224
|
+
run: npm test
|
|
225
|
+
|
|
226
|
+
- name: Run coverage
|
|
227
|
+
if: matrix.coverage
|
|
228
|
+
run: npm run test:coverage
|
|
229
|
+
|
|
230
|
+
e2e:
|
|
231
|
+
name: E2E Tests
|
|
20
232
|
runs-on: ubuntu-latest
|
|
233
|
+
strategy:
|
|
234
|
+
matrix:
|
|
235
|
+
browser: [chromium, firefox, webkit]
|
|
236
|
+
shard: [1, 2, 3]
|
|
21
237
|
|
|
22
238
|
steps:
|
|
23
|
-
-
|
|
239
|
+
- name: Checkout
|
|
240
|
+
uses: actions/checkout@v4
|
|
24
241
|
|
|
25
|
-
-
|
|
242
|
+
- name: Setup Node.js
|
|
243
|
+
uses: actions/setup-node@v4
|
|
26
244
|
with:
|
|
27
|
-
node-version:
|
|
245
|
+
node-version: 20
|
|
28
246
|
cache: 'npm'
|
|
29
247
|
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
248
|
+
- name: Install dependencies
|
|
249
|
+
run: npm ci
|
|
250
|
+
|
|
251
|
+
- name: Install Playwright
|
|
252
|
+
run: npx playwright install --with-deps ${{ matrix.browser }}
|
|
253
|
+
|
|
254
|
+
- name: Run E2E tests
|
|
255
|
+
run: npx playwright test --project=${{ matrix.browser }} --shard=${{ matrix.shard }}/3
|
|
256
|
+
|
|
257
|
+
- name: Upload test results
|
|
258
|
+
if: always()
|
|
259
|
+
uses: actions/upload-artifact@v4
|
|
260
|
+
with:
|
|
261
|
+
name: playwright-report-${{ matrix.browser }}-${{ matrix.shard }}
|
|
262
|
+
path: playwright-report/
|
|
34
263
|
```
|
|
35
264
|
|
|
36
|
-
|
|
265
|
+
### 3. Deployment Workflow
|
|
266
|
+
|
|
37
267
|
```yaml
|
|
38
|
-
deploy
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
268
|
+
# .github/workflows/deploy.yml
|
|
269
|
+
name: Deploy
|
|
270
|
+
|
|
271
|
+
on:
|
|
272
|
+
push:
|
|
273
|
+
branches: [main]
|
|
274
|
+
workflow_dispatch:
|
|
275
|
+
inputs:
|
|
276
|
+
environment:
|
|
277
|
+
description: 'Deployment environment'
|
|
278
|
+
required: true
|
|
279
|
+
type: choice
|
|
280
|
+
options:
|
|
281
|
+
- staging
|
|
282
|
+
- production
|
|
283
|
+
|
|
284
|
+
jobs:
|
|
285
|
+
build:
|
|
286
|
+
name: Build
|
|
287
|
+
runs-on: ubuntu-latest
|
|
288
|
+
outputs:
|
|
289
|
+
version: ${{ steps.version.outputs.version }}
|
|
290
|
+
|
|
291
|
+
steps:
|
|
292
|
+
- name: Checkout
|
|
293
|
+
uses: actions/checkout@v4
|
|
294
|
+
|
|
295
|
+
- name: Setup Node.js
|
|
296
|
+
uses: actions/setup-node@v4
|
|
297
|
+
with:
|
|
298
|
+
node-version: 20
|
|
299
|
+
cache: 'npm'
|
|
300
|
+
|
|
301
|
+
- name: Install dependencies
|
|
302
|
+
run: npm ci
|
|
303
|
+
|
|
304
|
+
- name: Build
|
|
305
|
+
run: npm run build
|
|
306
|
+
|
|
307
|
+
- name: Get version
|
|
308
|
+
id: version
|
|
309
|
+
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
|
|
310
|
+
|
|
311
|
+
- name: Upload build
|
|
312
|
+
uses: actions/upload-artifact@v4
|
|
313
|
+
with:
|
|
314
|
+
name: build-${{ steps.version.outputs.version }}
|
|
315
|
+
path: dist/
|
|
316
|
+
|
|
317
|
+
deploy-staging:
|
|
318
|
+
name: Deploy to Staging
|
|
319
|
+
needs: build
|
|
320
|
+
runs-on: ubuntu-latest
|
|
321
|
+
environment:
|
|
322
|
+
name: staging
|
|
323
|
+
url: https://staging.example.com
|
|
324
|
+
|
|
325
|
+
steps:
|
|
326
|
+
- name: Download build
|
|
327
|
+
uses: actions/download-artifact@v4
|
|
328
|
+
with:
|
|
329
|
+
name: build-${{ needs.build.outputs.version }}
|
|
330
|
+
path: dist/
|
|
331
|
+
|
|
332
|
+
- name: Deploy to staging
|
|
333
|
+
run: |
|
|
334
|
+
echo "Deploying version ${{ needs.build.outputs.version }} to staging"
|
|
335
|
+
# Add deployment commands here
|
|
336
|
+
|
|
337
|
+
- name: Run smoke tests
|
|
338
|
+
run: |
|
|
339
|
+
curl -f https://staging.example.com/health || exit 1
|
|
340
|
+
|
|
341
|
+
deploy-production:
|
|
342
|
+
name: Deploy to Production
|
|
343
|
+
needs: [build, deploy-staging]
|
|
344
|
+
runs-on: ubuntu-latest
|
|
345
|
+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production'
|
|
346
|
+
environment:
|
|
347
|
+
name: production
|
|
348
|
+
url: https://example.com
|
|
349
|
+
|
|
350
|
+
steps:
|
|
351
|
+
- name: Download build
|
|
352
|
+
uses: actions/download-artifact@v4
|
|
353
|
+
with:
|
|
354
|
+
name: build-${{ needs.build.outputs.version }}
|
|
355
|
+
path: dist/
|
|
356
|
+
|
|
357
|
+
- name: Deploy to production
|
|
358
|
+
run: |
|
|
359
|
+
echo "Deploying version ${{ needs.build.outputs.version }} to production"
|
|
360
|
+
# Add deployment commands here
|
|
361
|
+
|
|
362
|
+
- name: Notify deployment
|
|
363
|
+
uses: slackapi/slack-github-action@v1
|
|
364
|
+
with:
|
|
365
|
+
payload: |
|
|
366
|
+
{
|
|
367
|
+
"text": "Deployed v${{ needs.build.outputs.version }} to production"
|
|
368
|
+
}
|
|
369
|
+
env:
|
|
370
|
+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### 4. Reusable Composite Action
|
|
374
|
+
|
|
375
|
+
```yaml
|
|
376
|
+
# .github/actions/setup-node-env/action.yml
|
|
377
|
+
name: 'Setup Node Environment'
|
|
378
|
+
description: 'Setup Node.js with caching and dependencies'
|
|
379
|
+
|
|
380
|
+
inputs:
|
|
381
|
+
node-version:
|
|
382
|
+
description: 'Node.js version'
|
|
383
|
+
required: false
|
|
384
|
+
default: '20'
|
|
385
|
+
package-manager:
|
|
386
|
+
description: 'Package manager (npm, pnpm, yarn)'
|
|
387
|
+
required: false
|
|
388
|
+
default: 'npm'
|
|
389
|
+
install-deps:
|
|
390
|
+
description: 'Install dependencies'
|
|
391
|
+
required: false
|
|
392
|
+
default: 'true'
|
|
42
393
|
|
|
394
|
+
outputs:
|
|
395
|
+
cache-hit:
|
|
396
|
+
description: 'Whether cache was hit'
|
|
397
|
+
value: ${{ steps.cache.outputs.cache-hit }}
|
|
398
|
+
|
|
399
|
+
runs:
|
|
400
|
+
using: 'composite'
|
|
43
401
|
steps:
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
402
|
+
- name: Setup pnpm
|
|
403
|
+
if: inputs.package-manager == 'pnpm'
|
|
404
|
+
uses: pnpm/action-setup@v2
|
|
405
|
+
with:
|
|
406
|
+
version: 8
|
|
407
|
+
|
|
408
|
+
- name: Setup Node.js
|
|
409
|
+
uses: actions/setup-node@v4
|
|
47
410
|
with:
|
|
48
|
-
|
|
411
|
+
node-version: ${{ inputs.node-version }}
|
|
412
|
+
cache: ${{ inputs.package-manager }}
|
|
413
|
+
|
|
414
|
+
- name: Get cache directory
|
|
415
|
+
id: cache-dir
|
|
416
|
+
shell: bash
|
|
417
|
+
run: |
|
|
418
|
+
if [ "${{ inputs.package-manager }}" = "npm" ]; then
|
|
419
|
+
echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
|
420
|
+
elif [ "${{ inputs.package-manager }}" = "pnpm" ]; then
|
|
421
|
+
echo "dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
422
|
+
else
|
|
423
|
+
echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
|
424
|
+
fi
|
|
425
|
+
|
|
426
|
+
- name: Cache dependencies
|
|
427
|
+
id: cache
|
|
428
|
+
uses: actions/cache@v4
|
|
429
|
+
with:
|
|
430
|
+
path: ${{ steps.cache-dir.outputs.dir }}
|
|
431
|
+
key: ${{ runner.os }}-${{ inputs.package-manager }}-${{ hashFiles('**/package-lock.json', '**/pnpm-lock.yaml', '**/yarn.lock') }}
|
|
432
|
+
restore-keys: |
|
|
433
|
+
${{ runner.os }}-${{ inputs.package-manager }}-
|
|
434
|
+
|
|
435
|
+
- name: Install dependencies
|
|
436
|
+
if: inputs.install-deps == 'true'
|
|
437
|
+
shell: bash
|
|
438
|
+
run: |
|
|
439
|
+
if [ "${{ inputs.package-manager }}" = "npm" ]; then
|
|
440
|
+
npm ci
|
|
441
|
+
elif [ "${{ inputs.package-manager }}" = "pnpm" ]; then
|
|
442
|
+
pnpm install --frozen-lockfile
|
|
443
|
+
else
|
|
444
|
+
yarn install --frozen-lockfile
|
|
445
|
+
fi
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### 5. Docker Build and Push
|
|
449
|
+
|
|
450
|
+
```yaml
|
|
451
|
+
# .github/workflows/docker.yml
|
|
452
|
+
name: Docker Build
|
|
453
|
+
|
|
454
|
+
on:
|
|
455
|
+
push:
|
|
456
|
+
branches: [main]
|
|
457
|
+
tags: ['v*']
|
|
458
|
+
pull_request:
|
|
459
|
+
branches: [main]
|
|
460
|
+
|
|
461
|
+
env:
|
|
462
|
+
REGISTRY: ghcr.io
|
|
463
|
+
IMAGE_NAME: ${{ github.repository }}
|
|
464
|
+
|
|
465
|
+
jobs:
|
|
466
|
+
build:
|
|
467
|
+
name: Build and Push
|
|
468
|
+
runs-on: ubuntu-latest
|
|
469
|
+
permissions:
|
|
470
|
+
contents: read
|
|
471
|
+
packages: write
|
|
472
|
+
|
|
473
|
+
steps:
|
|
474
|
+
- name: Checkout
|
|
475
|
+
uses: actions/checkout@v4
|
|
476
|
+
|
|
477
|
+
- name: Set up QEMU
|
|
478
|
+
uses: docker/setup-qemu-action@v3
|
|
479
|
+
|
|
480
|
+
- name: Set up Docker Buildx
|
|
481
|
+
uses: docker/setup-buildx-action@v3
|
|
482
|
+
|
|
483
|
+
- name: Login to Container Registry
|
|
484
|
+
if: github.event_name != 'pull_request'
|
|
485
|
+
uses: docker/login-action@v3
|
|
486
|
+
with:
|
|
487
|
+
registry: ${{ env.REGISTRY }}
|
|
488
|
+
username: ${{ github.actor }}
|
|
489
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
490
|
+
|
|
491
|
+
- name: Extract metadata
|
|
492
|
+
id: meta
|
|
493
|
+
uses: docker/metadata-action@v5
|
|
494
|
+
with:
|
|
495
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
496
|
+
tags: |
|
|
497
|
+
type=ref,event=branch
|
|
498
|
+
type=ref,event=pr
|
|
499
|
+
type=semver,pattern={{version}}
|
|
500
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
501
|
+
type=sha
|
|
502
|
+
|
|
503
|
+
- name: Build and push
|
|
504
|
+
uses: docker/build-push-action@v5
|
|
505
|
+
with:
|
|
506
|
+
context: .
|
|
507
|
+
platforms: linux/amd64,linux/arm64
|
|
508
|
+
push: ${{ github.event_name != 'pull_request' }}
|
|
509
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
510
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
511
|
+
cache-from: type=gha
|
|
512
|
+
cache-to: type=gha,mode=max
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### 6. Security Scanning
|
|
516
|
+
|
|
517
|
+
```yaml
|
|
518
|
+
# .github/workflows/security.yml
|
|
519
|
+
name: Security
|
|
520
|
+
|
|
521
|
+
on:
|
|
522
|
+
push:
|
|
523
|
+
branches: [main]
|
|
524
|
+
pull_request:
|
|
525
|
+
schedule:
|
|
526
|
+
- cron: '0 0 * * 0' # Weekly
|
|
527
|
+
|
|
528
|
+
jobs:
|
|
529
|
+
codeql:
|
|
530
|
+
name: CodeQL Analysis
|
|
531
|
+
runs-on: ubuntu-latest
|
|
532
|
+
permissions:
|
|
533
|
+
security-events: write
|
|
534
|
+
|
|
535
|
+
steps:
|
|
536
|
+
- name: Checkout
|
|
537
|
+
uses: actions/checkout@v4
|
|
538
|
+
|
|
539
|
+
- name: Initialize CodeQL
|
|
540
|
+
uses: github/codeql-action/init@v3
|
|
541
|
+
with:
|
|
542
|
+
languages: javascript, typescript
|
|
543
|
+
|
|
544
|
+
- name: Autobuild
|
|
545
|
+
uses: github/codeql-action/autobuild@v3
|
|
546
|
+
|
|
547
|
+
- name: Perform CodeQL Analysis
|
|
548
|
+
uses: github/codeql-action/analyze@v3
|
|
549
|
+
|
|
550
|
+
dependency-review:
|
|
551
|
+
name: Dependency Review
|
|
552
|
+
runs-on: ubuntu-latest
|
|
553
|
+
if: github.event_name == 'pull_request'
|
|
554
|
+
|
|
555
|
+
steps:
|
|
556
|
+
- name: Checkout
|
|
557
|
+
uses: actions/checkout@v4
|
|
558
|
+
|
|
559
|
+
- name: Dependency Review
|
|
560
|
+
uses: actions/dependency-review-action@v3
|
|
561
|
+
with:
|
|
562
|
+
fail-on-severity: high
|
|
563
|
+
|
|
564
|
+
secrets-scan:
|
|
565
|
+
name: Secret Scanning
|
|
566
|
+
runs-on: ubuntu-latest
|
|
567
|
+
|
|
568
|
+
steps:
|
|
569
|
+
- name: Checkout
|
|
570
|
+
uses: actions/checkout@v4
|
|
571
|
+
with:
|
|
572
|
+
fetch-depth: 0
|
|
573
|
+
|
|
574
|
+
- name: TruffleHog Scan
|
|
575
|
+
uses: trufflesecurity/trufflehog@main
|
|
576
|
+
with:
|
|
577
|
+
extra_args: --only-verified
|
|
578
|
+
|
|
579
|
+
container-scan:
|
|
580
|
+
name: Container Scanning
|
|
581
|
+
runs-on: ubuntu-latest
|
|
582
|
+
needs: build
|
|
583
|
+
|
|
584
|
+
steps:
|
|
585
|
+
- name: Checkout
|
|
586
|
+
uses: actions/checkout@v4
|
|
587
|
+
|
|
588
|
+
- name: Build image
|
|
589
|
+
run: docker build -t app:scan .
|
|
590
|
+
|
|
591
|
+
- name: Run Trivy scanner
|
|
592
|
+
uses: aquasecurity/trivy-action@master
|
|
593
|
+
with:
|
|
594
|
+
image-ref: 'app:scan'
|
|
595
|
+
format: 'sarif'
|
|
596
|
+
output: 'trivy-results.sarif'
|
|
597
|
+
|
|
598
|
+
- name: Upload scan results
|
|
599
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
600
|
+
with:
|
|
601
|
+
sarif_file: 'trivy-results.sarif'
|
|
49
602
|
```
|
|
50
603
|
|
|
51
|
-
##
|
|
604
|
+
## Use Cases
|
|
605
|
+
|
|
606
|
+
### Release Workflow
|
|
607
|
+
|
|
52
608
|
```yaml
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
609
|
+
# .github/workflows/release.yml
|
|
610
|
+
name: Release
|
|
611
|
+
|
|
612
|
+
on:
|
|
613
|
+
push:
|
|
614
|
+
tags: ['v*']
|
|
615
|
+
|
|
616
|
+
jobs:
|
|
617
|
+
release:
|
|
618
|
+
name: Create Release
|
|
619
|
+
runs-on: ubuntu-latest
|
|
620
|
+
permissions:
|
|
621
|
+
contents: write
|
|
622
|
+
|
|
623
|
+
steps:
|
|
624
|
+
- name: Checkout
|
|
625
|
+
uses: actions/checkout@v4
|
|
626
|
+
with:
|
|
627
|
+
fetch-depth: 0
|
|
628
|
+
|
|
629
|
+
- name: Generate changelog
|
|
630
|
+
id: changelog
|
|
631
|
+
uses: orhun/git-cliff-action@v2
|
|
632
|
+
with:
|
|
633
|
+
args: --latest
|
|
634
|
+
|
|
635
|
+
- name: Create Release
|
|
636
|
+
uses: softprops/action-gh-release@v1
|
|
637
|
+
with:
|
|
638
|
+
body: ${{ steps.changelog.outputs.content }}
|
|
639
|
+
draft: false
|
|
640
|
+
prerelease: ${{ contains(github.ref, '-') }}
|
|
641
|
+
env:
|
|
642
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### Scheduled Jobs
|
|
646
|
+
|
|
647
|
+
```yaml
|
|
648
|
+
# .github/workflows/scheduled.yml
|
|
649
|
+
name: Scheduled Tasks
|
|
650
|
+
|
|
651
|
+
on:
|
|
652
|
+
schedule:
|
|
653
|
+
- cron: '0 0 * * *' # Daily at midnight
|
|
654
|
+
|
|
655
|
+
jobs:
|
|
656
|
+
cleanup:
|
|
657
|
+
name: Cleanup Old Artifacts
|
|
658
|
+
runs-on: ubuntu-latest
|
|
659
|
+
|
|
660
|
+
steps:
|
|
661
|
+
- name: Delete old artifacts
|
|
662
|
+
uses: actions/github-script@v7
|
|
663
|
+
with:
|
|
664
|
+
script: |
|
|
665
|
+
const days = 30;
|
|
666
|
+
const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;
|
|
667
|
+
|
|
668
|
+
const artifacts = await github.rest.actions.listArtifactsForRepo({
|
|
669
|
+
owner: context.repo.owner,
|
|
670
|
+
repo: context.repo.repo,
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
for (const artifact of artifacts.data.artifacts) {
|
|
674
|
+
if (new Date(artifact.created_at).getTime() < cutoff) {
|
|
675
|
+
await github.rest.actions.deleteArtifact({
|
|
676
|
+
owner: context.repo.owner,
|
|
677
|
+
repo: context.repo.repo,
|
|
678
|
+
artifact_id: artifact.id,
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
}
|
|
57
682
|
```
|
|
58
683
|
|
|
59
684
|
## Best Practices
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
-
|
|
685
|
+
|
|
686
|
+
### Do's
|
|
687
|
+
|
|
688
|
+
- Use concurrency groups to cancel redundant runs
|
|
689
|
+
- Cache dependencies for faster builds
|
|
690
|
+
- Use matrix strategies for cross-platform testing
|
|
691
|
+
- Implement proper secret management
|
|
692
|
+
- Use environment protection rules
|
|
693
|
+
- Add status badges to README
|
|
694
|
+
- Use reusable workflows and composite actions
|
|
695
|
+
- Implement security scanning
|
|
696
|
+
- Set timeouts on jobs
|
|
697
|
+
- Use artifact retention policies
|
|
698
|
+
|
|
699
|
+
### Don'ts
|
|
700
|
+
|
|
701
|
+
- Don't hardcode secrets in workflows
|
|
702
|
+
- Don't skip concurrency controls
|
|
703
|
+
- Don't ignore failing security scans
|
|
704
|
+
- Don't use deprecated action versions
|
|
705
|
+
- Don't skip caching for dependencies
|
|
706
|
+
- Don't run unnecessary jobs on PRs
|
|
707
|
+
- Don't ignore workflow permissions
|
|
708
|
+
- Don't skip environment approvals for production
|
|
709
|
+
- Don't use self-hosted runners without security review
|
|
710
|
+
- Don't ignore workflow run costs
|
|
711
|
+
|
|
712
|
+
## References
|
|
713
|
+
|
|
714
|
+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
|
715
|
+
- [Workflow Syntax](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions)
|
|
716
|
+
- [GitHub Actions Marketplace](https://github.com/marketplace?type=actions)
|
|
717
|
+
- [Security Hardening](https://docs.github.com/en/actions/security-guides)
|
|
718
|
+
- [Reusable Workflows](https://docs.github.com/en/actions/using-workflows/reusing-workflows)
|