@slamb2k/mad-skills 2.0.14 → 2.0.16

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.
@@ -0,0 +1,457 @@
1
+ # Platform Deployment Guides
2
+
3
+ Deployment commands and manifests for each supported container platform.
4
+ These are inserted into the `{*_DEPLOY_COMMANDS}` placeholders in the
5
+ pipeline templates.
6
+
7
+ Template variables available in all commands:
8
+ - `{REGISTRY}`: Full registry URL
9
+ - `{IMAGE_NAME}`: Image name
10
+ - `{TAG}`: Image tag (SHA or version)
11
+ - `{PORT}`: Application port
12
+ - `{ENV_NAME}`: Environment name (dev, staging, prod)
13
+
14
+ ---
15
+
16
+ ## Azure Container Apps
17
+
18
+ Recommended for most workloads. Serverless containers with auto-scaling,
19
+ built-in ingress, managed TLS.
20
+
21
+ ### Workflow steps (GitHub Actions)
22
+
23
+ ```yaml
24
+ - name: Login to Azure
25
+ uses: azure/login@v2
26
+ with:
27
+ creds: ${{ secrets.AZURE_CREDENTIALS }}
28
+
29
+ - name: Deploy to Container Apps
30
+ uses: azure/container-apps-deploy-action@v2
31
+ with:
32
+ imageToDeploy: {REGISTRY}/{IMAGE_NAME}:{TAG}
33
+ containerAppName: {APP_NAME}-{ENV_NAME}
34
+ resourceGroup: {RESOURCE_GROUP}
35
+ containerAppEnvironment: {ENV_NAME}
36
+ ```
37
+
38
+ ### Infrastructure setup (Bicep)
39
+
40
+ Generate `deploy/azure-container-apps.bicep` if user wants IaC:
41
+
42
+ ```bicep
43
+ param location string = resourceGroup().location
44
+ param envName string
45
+ param imageName string
46
+ param registryServer string
47
+
48
+ resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-03-01' = {
49
+ name: 'cae-${envName}'
50
+ location: location
51
+ properties: {
52
+ zoneRedundant: envName == 'prod'
53
+ }
54
+ }
55
+
56
+ resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
57
+ name: 'ca-${envName}'
58
+ location: location
59
+ properties: {
60
+ managedEnvironmentId: containerAppEnv.id
61
+ configuration: {
62
+ ingress: {
63
+ external: true
64
+ targetPort: {PORT}
65
+ transport: 'auto'
66
+ }
67
+ registries: [
68
+ {
69
+ server: registryServer
70
+ identity: 'system'
71
+ }
72
+ ]
73
+ }
74
+ template: {
75
+ containers: [
76
+ {
77
+ name: 'app'
78
+ image: imageName
79
+ resources: {
80
+ cpu: json('0.5')
81
+ memory: '1Gi'
82
+ }
83
+ probes: [
84
+ {
85
+ type: 'Liveness'
86
+ httpGet: {
87
+ path: '/healthz'
88
+ port: {PORT}
89
+ }
90
+ periodSeconds: 30
91
+ }
92
+ ]
93
+ }
94
+ ]
95
+ scale: {
96
+ minReplicas: envName == 'prod' ? 2 : 1
97
+ maxReplicas: envName == 'prod' ? 10 : 3
98
+ }
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### Required secrets
105
+
106
+ - `AZURE_CREDENTIALS`: Service principal JSON for Azure login
107
+ - Registry access: Use managed identity (preferred) or registry credentials
108
+
109
+ ---
110
+
111
+ ## Azure App Service for Containers
112
+
113
+ Traditional PaaS with deployment slots. Good for teams already using App Service.
114
+
115
+ ### Workflow steps
116
+
117
+ ```yaml
118
+ - name: Login to Azure
119
+ uses: azure/login@v2
120
+ with:
121
+ creds: ${{ secrets.AZURE_CREDENTIALS }}
122
+
123
+ - name: Deploy to App Service
124
+ uses: azure/webapps-deploy@v3
125
+ with:
126
+ app-name: {APP_NAME}-{ENV_NAME}
127
+ images: {REGISTRY}/{IMAGE_NAME}:{TAG}
128
+ slot-name: staging # For blue-green: deploy to slot first
129
+ ```
130
+
131
+ ### Blue-green with slots
132
+
133
+ ```yaml
134
+ - name: Deploy to staging slot
135
+ uses: azure/webapps-deploy@v3
136
+ with:
137
+ app-name: {APP_NAME}-{ENV_NAME}
138
+ images: {REGISTRY}/{IMAGE_NAME}:{TAG}
139
+ slot-name: staging
140
+
141
+ - name: Smoke test staging slot
142
+ run: curl -f "https://{APP_NAME}-{ENV_NAME}-staging.azurewebsites.net/healthz"
143
+
144
+ - name: Swap slots
145
+ run: az webapp deployment slot swap -g {RESOURCE_GROUP} -n {APP_NAME}-{ENV_NAME} --slot staging --target-slot production
146
+ ```
147
+
148
+ ---
149
+
150
+ ## AWS Fargate (ECS)
151
+
152
+ Serverless containers on AWS. Requires ECS cluster, task definition, service.
153
+
154
+ ### Workflow steps
155
+
156
+ ```yaml
157
+ - name: Configure AWS credentials
158
+ uses: aws-actions/configure-aws-credentials@v4
159
+ with:
160
+ role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
161
+ aws-region: ${{ vars.AWS_REGION }}
162
+
163
+ - name: Login to ECR
164
+ uses: aws-actions/amazon-ecr-login@v2
165
+
166
+ - name: Update ECS task definition
167
+ id: task-def
168
+ uses: aws-actions/amazon-ecs-render-task-definition@v1
169
+ with:
170
+ task-definition: deploy/ecs-task-{ENV_NAME}.json
171
+ container-name: app
172
+ image: {REGISTRY}/{IMAGE_NAME}:{TAG}
173
+
174
+ - name: Deploy to ECS
175
+ uses: aws-actions/amazon-ecs-deploy-task-definition@v2
176
+ with:
177
+ task-definition: ${{ steps.task-def.outputs.task-definition }}
178
+ service: {SERVICE_NAME}-{ENV_NAME}
179
+ cluster: {CLUSTER_NAME}
180
+ wait-for-service-stability: true
181
+ ```
182
+
183
+ ### Task definition template
184
+
185
+ Generate `deploy/ecs-task-{ENV_NAME}.json`:
186
+
187
+ ```json
188
+ {
189
+ "family": "{IMAGE_NAME}-{ENV_NAME}",
190
+ "networkMode": "awsvpc",
191
+ "requiresCompatibilities": ["FARGATE"],
192
+ "cpu": "256",
193
+ "memory": "512",
194
+ "containerDefinitions": [
195
+ {
196
+ "name": "app",
197
+ "image": "{REGISTRY}/{IMAGE_NAME}:{TAG}",
198
+ "portMappings": [{ "containerPort": {PORT} }],
199
+ "healthCheck": {
200
+ "command": ["CMD-SHELL", "curl -f http://localhost:{PORT}/healthz || exit 1"],
201
+ "interval": 30,
202
+ "timeout": 5,
203
+ "retries": 3,
204
+ "startPeriod": 15
205
+ },
206
+ "logConfiguration": {
207
+ "logDriver": "awslogs",
208
+ "options": {
209
+ "awslogs-group": "/ecs/{IMAGE_NAME}-{ENV_NAME}",
210
+ "awslogs-region": "{AWS_REGION}",
211
+ "awslogs-stream-prefix": "ecs"
212
+ }
213
+ }
214
+ }
215
+ ]
216
+ }
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Google Cloud Run
222
+
223
+ Serverless containers on GCP. Simplest deployment model.
224
+
225
+ ### Workflow steps
226
+
227
+ ```yaml
228
+ - name: Authenticate to Google Cloud
229
+ uses: google-github-actions/auth@v2
230
+ with:
231
+ workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
232
+ service_account: ${{ secrets.SA_EMAIL }}
233
+
234
+ - name: Deploy to Cloud Run
235
+ uses: google-github-actions/deploy-cloudrun@v2
236
+ with:
237
+ service: {IMAGE_NAME}-{ENV_NAME}
238
+ region: {GCP_REGION}
239
+ image: {REGISTRY}/{IMAGE_NAME}:{TAG}
240
+ flags: |
241
+ --port={PORT}
242
+ --min-instances=${{ env.ENV_NAME == 'prod' && '2' || '0' }}
243
+ --max-instances=${{ env.ENV_NAME == 'prod' && '100' || '10' }}
244
+ ```
245
+
246
+ ### Required setup
247
+
248
+ - Workload Identity Federation (preferred over service account keys)
249
+ - Artifact Registry repository
250
+ - Cloud Run service in each region/environment
251
+
252
+ ---
253
+
254
+ ## Kubernetes
255
+
256
+ Most flexible. Generates Helm chart or kustomize overlays.
257
+
258
+ ### Helm chart structure
259
+
260
+ Generate `deploy/helm/{IMAGE_NAME}/`:
261
+
262
+ ```
263
+ deploy/helm/{IMAGE_NAME}/
264
+ ├── Chart.yaml
265
+ ├── values.yaml # Default values
266
+ ├── values-dev.yaml # Dev overrides
267
+ ├── values-staging.yaml # Staging overrides
268
+ ├── values-prod.yaml # Prod overrides
269
+ └── templates/
270
+ ├── deployment.yaml
271
+ ├── service.yaml
272
+ ├── ingress.yaml
273
+ └── hpa.yaml
274
+ ```
275
+
276
+ ### Workflow steps
277
+
278
+ ```yaml
279
+ - name: Set up kubectl
280
+ uses: azure/setup-kubectl@v4
281
+
282
+ - name: Set kubeconfig
283
+ run: echo "${{ secrets.KUBECONFIG_{ENV_NAME} }}" | base64 -d > kubeconfig
284
+ env:
285
+ KUBECONFIG: kubeconfig
286
+
287
+ - name: Deploy with Helm
288
+ run: |
289
+ helm upgrade --install {IMAGE_NAME} deploy/helm/{IMAGE_NAME} \
290
+ --namespace {ENV_NAME} \
291
+ --values deploy/helm/{IMAGE_NAME}/values-{ENV_NAME}.yaml \
292
+ --set image.repository={REGISTRY}/{IMAGE_NAME} \
293
+ --set image.tag={TAG} \
294
+ --wait --timeout 5m
295
+ ```
296
+
297
+ ### values.yaml template
298
+
299
+ ```yaml
300
+ replicaCount: 1
301
+
302
+ image:
303
+ repository: {REGISTRY}/{IMAGE_NAME}
304
+ tag: latest
305
+ pullPolicy: IfNotPresent
306
+
307
+ service:
308
+ type: ClusterIP
309
+ port: {PORT}
310
+
311
+ ingress:
312
+ enabled: false
313
+ className: nginx
314
+
315
+ resources:
316
+ requests:
317
+ cpu: 100m
318
+ memory: 128Mi
319
+ limits:
320
+ cpu: 500m
321
+ memory: 512Mi
322
+
323
+ livenessProbe:
324
+ httpGet:
325
+ path: /healthz
326
+ port: {PORT}
327
+ initialDelaySeconds: 15
328
+ periodSeconds: 30
329
+
330
+ autoscaling:
331
+ enabled: false
332
+ minReplicas: 1
333
+ maxReplicas: 10
334
+ targetCPUUtilizationPercentage: 80
335
+ ```
336
+
337
+ ---
338
+
339
+ ## Dokku
340
+
341
+ Self-hosted PaaS. Simplest deployment — git push based.
342
+
343
+ ### Workflow steps
344
+
345
+ ```yaml
346
+ - name: Deploy to Dokku
347
+ uses: dokku/github-action@master
348
+ with:
349
+ git_remote_url: ssh://dokku@{DOKKU_HOST}:22/{APP_NAME}-{ENV_NAME}
350
+ ssh_private_key: ${{ secrets.DOKKU_SSH_KEY }}
351
+ git_push_flags: --force
352
+ deploy_docker_image: {REGISTRY}/{IMAGE_NAME}:{TAG}
353
+ ```
354
+
355
+ ### Setup commands (run once on Dokku host)
356
+
357
+ ```bash
358
+ dokku apps:create {APP_NAME}-{ENV_NAME}
359
+ dokku ports:set {APP_NAME}-{ENV_NAME} http:80:{PORT}
360
+ dokku letsencrypt:enable {APP_NAME}-{ENV_NAME}
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Coolify
366
+
367
+ Self-hosted PaaS with API. Deploy via webhook or API call.
368
+
369
+ ### Workflow steps
370
+
371
+ ```yaml
372
+ - name: Deploy to Coolify
373
+ run: |
374
+ curl -X POST "https://{COOLIFY_HOST}/api/v1/deploy" \
375
+ -H "Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}" \
376
+ -H "Content-Type: application/json" \
377
+ -d '{
378
+ "uuid": "{COOLIFY_APP_UUID}",
379
+ "image": "{REGISTRY}/{IMAGE_NAME}:{TAG}",
380
+ "force_rebuild": false
381
+ }'
382
+ ```
383
+
384
+ ---
385
+
386
+ ## CapRover
387
+
388
+ Self-hosted PaaS. Uses captain-definition file.
389
+
390
+ ### captain-definition
391
+
392
+ Generate `captain-definition`:
393
+
394
+ ```json
395
+ {
396
+ "schemaVersion": 2,
397
+ "imageName": "{REGISTRY}/{IMAGE_NAME}:{TAG}"
398
+ }
399
+ ```
400
+
401
+ ### Workflow steps
402
+
403
+ ```yaml
404
+ - name: Deploy to CapRover
405
+ uses: caprover/deploy-from-github@v1.1.2
406
+ with:
407
+ server: https://{CAPROVER_HOST}
408
+ app: {APP_NAME}-{ENV_NAME}
409
+ token: ${{ secrets.CAPROVER_TOKEN }}
410
+ image: {REGISTRY}/{IMAGE_NAME}:{TAG}
411
+ ```
412
+
413
+ ---
414
+
415
+ ## Rollback Patterns
416
+
417
+ ### Simple rollback
418
+
419
+ Add a rollback step that triggers on deploy failure:
420
+
421
+ ```yaml
422
+ - name: Rollback on failure
423
+ if: failure()
424
+ run: |
425
+ PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "latest")
426
+ # Redeploy with previous tag using same deploy command
427
+ echo "Rolling back to $PREV_TAG"
428
+ ```
429
+
430
+ ### Blue-green (Azure App Service example)
431
+
432
+ See Azure App Service section — use deployment slots.
433
+
434
+ ### Canary (Kubernetes)
435
+
436
+ Requires a service mesh (Istio, Linkerd) or ingress controller with traffic splitting.
437
+ Generate an Istio VirtualService:
438
+
439
+ ```yaml
440
+ apiVersion: networking.istio.io/v1beta1
441
+ kind: VirtualService
442
+ metadata:
443
+ name: {IMAGE_NAME}
444
+ spec:
445
+ hosts:
446
+ - {IMAGE_NAME}
447
+ http:
448
+ - route:
449
+ - destination:
450
+ host: {IMAGE_NAME}
451
+ subset: stable
452
+ weight: 90
453
+ - destination:
454
+ host: {IMAGE_NAME}
455
+ subset: canary
456
+ weight: 10
457
+ ```
@@ -0,0 +1,36 @@
1
+ [
2
+ {
3
+ "name": "banner-display",
4
+ "prompt": "/dock",
5
+ "assertions": [
6
+ { "type": "contains", "value": "██" },
7
+ { "type": "regex", "value": "🐳|📦|🚀|⚓|🏗️|🔒|🌊|🎯" },
8
+ { "type": "semantic", "value": "Displays an ASCII art banner for the dock skill before doing anything else" }
9
+ ]
10
+ },
11
+ {
12
+ "name": "detection-awareness",
13
+ "prompt": "/dock for a Node.js Express app with an existing GitHub Actions workflow",
14
+ "assertions": [
15
+ { "type": "semantic", "value": "Describes detecting or scanning the codebase for language, framework, existing CI configuration" },
16
+ { "type": "semantic", "value": "Mentions Node.js or Express as the detected stack" },
17
+ { "type": "semantic", "value": "Acknowledges existing GitHub Actions workflow" }
18
+ ]
19
+ },
20
+ {
21
+ "name": "build-once-philosophy",
22
+ "prompt": "/dock --skip-interview",
23
+ "assertions": [
24
+ { "type": "semantic", "value": "Explains or implements the build-once-promote-everywhere philosophy where images are built once and promoted through environments without rebuilding" },
25
+ { "type": "semantic", "value": "Mentions tagging images with git SHA or version for immutability" }
26
+ ]
27
+ },
28
+ {
29
+ "name": "multi-platform-support",
30
+ "prompt": "/dock I want to deploy to Azure Container Apps for prod and Dokku for dev",
31
+ "assertions": [
32
+ { "type": "semantic", "value": "Supports different deployment targets per environment" },
33
+ { "type": "semantic", "value": "References both Azure Container Apps and Dokku as deployment platforms" }
34
+ ]
35
+ }
36
+ ]