@polymorphism-tech/morph-spec 2.4.0 → 3.0.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/CLAUDE.md +158 -26
- package/LICENSE +72 -72
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +8 -0
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/content/.azure/README.md +293 -293
- package/content/.azure/docs/azure-devops-setup.md +454 -454
- package/content/.azure/docs/branch-strategy.md +398 -398
- package/content/.azure/docs/local-development.md +515 -515
- package/content/.azure/pipelines/pipeline-variables.yml +34 -34
- package/content/.azure/pipelines/prod-pipeline.yml +319 -319
- package/content/.azure/pipelines/staging-pipeline.yml +234 -234
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-deploy.md +529 -0
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -227
- package/content/.claude/commands/morph-troubleshoot.md +122 -122
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/infra/azure-deploy-specialist.md +699 -0
- package/content/.claude/skills/level-0-meta/README.md +7 -0
- package/content/.claude/skills/{checklists → level-0-meta}/morph-checklist.md +117 -117
- package/content/.claude/skills/level-1-workflows/README.md +7 -0
- package/content/.claude/skills/{workflows → level-1-workflows}/morph-replicate.md +213 -213
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-clarify.md +131 -131
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-design.md +213 -205
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-setup.md +106 -92
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-tasks.md +164 -164
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-uiux.md +169 -138
- package/content/.claude/skills/level-2-domains/README.md +14 -0
- package/content/.claude/skills/{specialists → level-2-domains/quality}/testing-specialist.md +126 -126
- package/content/.claude/skills/level-3-technologies/README.md +7 -0
- package/content/.claude/skills/level-4-patterns/README.md +7 -0
- package/content/.claude/skills/specialists/prompt-engineer.md +189 -0
- package/content/.claude/skills/specialists/seo-growth-hacker.md +320 -0
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +742 -358
- package/content/.morph/config/config.template.json +33 -0
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/enforcement-pipeline.md +668 -0
- package/content/.morph/examples/api-nextjs/README.md +241 -241
- package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/content/.morph/examples/api-nextjs/spec.md +399 -399
- package/content/.morph/examples/api-nextjs/tasks.md +168 -168
- package/content/.morph/examples/micro-saas/README.md +125 -125
- package/content/.morph/examples/micro-saas/contracts.cs +358 -358
- package/content/.morph/examples/micro-saas/decisions.md +246 -246
- package/content/.morph/examples/micro-saas/spec.md +236 -236
- package/content/.morph/examples/micro-saas/tasks.md +150 -150
- package/content/.morph/examples/multi-agent/README.md +309 -309
- package/content/.morph/examples/multi-agent/contracts.cs +433 -433
- package/content/.morph/examples/multi-agent/spec.md +479 -479
- package/content/.morph/examples/multi-agent/tasks.md +185 -185
- package/content/.morph/examples/scheduled-reports/decisions.md +158 -158
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -95
- package/content/.morph/examples/scheduled-reports/spec.md +267 -267
- package/content/.morph/examples/state-v3.json +188 -188
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +158 -0
- package/content/.morph/hooks/pre-commit-all.sh +48 -48
- package/content/.morph/hooks/pre-commit-specs.sh +49 -49
- package/content/.morph/hooks/pre-commit-tests.sh +60 -60
- package/content/.morph/hooks/task-completed.js +73 -0
- package/content/.morph/hooks/teammate-idle.js +68 -0
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -220
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-teams-workflow.md +474 -0
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/fluent-ui-setup.md +590 -590
- package/content/.morph/standards/migration-guide.md +514 -514
- package/content/.morph/standards/passkeys-auth.md +423 -423
- package/content/.morph/standards/vector-search-rag.md +536 -536
- package/content/.morph/state.json +17 -17
- package/content/.morph/templates/CONTEXT-FEATURE.md +276 -0
- package/content/.morph/templates/CONTEXT.md +170 -0
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/clarify-questions.md +159 -159
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -74
- package/content/.morph/templates/contracts/Entities.cs +25 -25
- package/content/.morph/templates/contracts/Queries.cs +74 -74
- package/content/.morph/templates/contracts/README.md +74 -74
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/design-system.css +226 -226
- package/content/.morph/templates/infra/.dockerignore.example +89 -89
- package/content/.morph/templates/infra/Dockerfile.example +82 -82
- package/content/.morph/templates/infra/README.md +286 -286
- package/content/.morph/templates/infra/app-insights.bicep +63 -63
- package/content/.morph/templates/infra/app-service.bicep +164 -164
- package/content/.morph/templates/infra/azure-pipelines-deploy.yml +480 -0
- package/content/.morph/templates/infra/container-app-env.bicep +49 -49
- package/content/.morph/templates/infra/container-app.bicep +156 -156
- package/content/.morph/templates/infra/deploy-checklist.md +426 -426
- package/content/.morph/templates/infra/deploy.ps1 +229 -229
- package/content/.morph/templates/infra/deploy.sh +208 -208
- package/content/.morph/templates/infra/key-vault.bicep +91 -91
- package/content/.morph/templates/infra/main.bicep +189 -189
- package/content/.morph/templates/infra/parameters.dev.json +29 -29
- package/content/.morph/templates/infra/parameters.prod.json +29 -29
- package/content/.morph/templates/infra/parameters.staging.json +29 -29
- package/content/.morph/templates/infra/sql-database.bicep +103 -103
- package/content/.morph/templates/infra/storage.bicep +106 -106
- package/content/.morph/templates/integrations/asaas-client.cs +387 -387
- package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/content/.morph/templates/integrations/clerk-config.cs +258 -258
- package/content/.morph/templates/job.cs +171 -171
- package/content/.morph/templates/migration.cs +83 -83
- package/content/.morph/templates/repository.cs +141 -141
- package/content/.morph/templates/saas/subscription.cs +347 -347
- package/content/.morph/templates/saas/tenant.cs +338 -338
- package/content/.morph/templates/service.cs +139 -139
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-design-system.md +286 -286
- package/content/.morph/templates/ui-flows.md +336 -336
- package/content/.morph/templates/ui-mockups.md +133 -133
- package/content/.morph/test-infra/example.bicep +59 -59
- package/content/README.md +79 -79
- package/detectors/config-detector.js +223 -223
- package/detectors/conversation-analyzer.js +163 -163
- package/detectors/index.js +84 -84
- package/detectors/standards-generator.js +275 -275
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
- package/docs/api/scripts/collapse.js +38 -38
- package/docs/api/scripts/commonNav.js +28 -28
- package/docs/api/scripts/linenumber.js +25 -25
- package/docs/api/scripts/nav.js +12 -12
- package/docs/api/scripts/polyfill.js +3 -3
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
- package/docs/api/scripts/prettify/lang-css.js +2 -2
- package/docs/api/scripts/prettify/prettify.js +28 -28
- package/docs/api/scripts/search.js +98 -98
- package/docs/api/styles/jsdoc.css +776 -776
- package/docs/api/styles/prettify.css +80 -80
- package/docs/examples.md +328 -328
- package/docs/templates.md +418 -418
- package/package.json +1 -1
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +83 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -193
- package/src/commands/create-story.js +351 -351
- package/src/commands/deploy.js +780 -0
- package/src/commands/detect-agents.js +34 -6
- package/src/commands/detect.js +104 -104
- package/src/commands/generate-context.js +40 -0
- package/src/commands/generate.js +149 -149
- package/src/commands/lint-fluent.js +352 -352
- package/src/commands/rollback-phase.js +185 -185
- package/src/commands/session-summary.js +291 -291
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +333 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/troubleshoot.js +222 -222
- package/src/commands/validate-blazor-state.js +210 -210
- package/src/commands/validate-blazor.js +156 -156
- package/src/commands/validate-css.js +84 -84
- package/src/commands/validate-phase.js +221 -221
- package/src/lib/blazor-concurrency-analyzer.js +288 -288
- package/src/lib/blazor-state-validator.js +291 -291
- package/src/lib/blazor-validator.js +374 -374
- package/src/lib/context-generator.js +513 -0
- package/src/lib/css-validator.js +352 -352
- package/src/lib/design-system-detector.js +187 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/design-system-scaffolder.js +299 -0
- package/src/lib/hook-executor.js +256 -0
- package/src/lib/learning-system.js +520 -520
- package/src/lib/mockup-generator.js +366 -366
- package/src/lib/spec-validator.js +258 -0
- package/src/lib/standards-context-injector.js +287 -0
- package/src/lib/team-orchestrator.js +322 -0
- package/src/lib/troubleshoot-grep.js +194 -194
- package/src/lib/troubleshoot-index.js +144 -144
- package/src/lib/ui-detector.js +350 -350
- package/src/lib/validation-runner.js +65 -13
- package/src/lib/validators/architecture-validator.js +387 -387
- package/src/lib/validators/design-system-validator.js +231 -0
- package/src/lib/validators/package-validator.js +360 -360
- package/src/lib/validators/ui-contrast-validator.js +422 -422
- package/src/utils/file-copier.js +9 -1
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- /package/content/.claude/skills/{checklists → level-0-meta}/code-review.md +0 -0
- /package/content/.claude/skills/{checklists → level-0-meta}/simulation-checklist.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/ai-agents}/ai-system-architect.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/architecture}/po-pm-advisor.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/architecture}/standards-architect.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/dotnet-senior.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/ef-modeler.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/hangfire-orchestrator.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/ms-agent-expert.md +0 -0
- /package/content/.claude/skills/{stacks/dotnet-blazor.md → level-2-domains/frontend/blazor-builder.md} +0 -0
- /package/content/.claude/skills/{stacks/dotnet-nextjs.md → level-2-domains/frontend/nextjs-expert.md} +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/frontend}/ui-ux-designer.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/infrastructure}/azure-architect.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/bicep-architect.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/container-specialist.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/devops-engineer.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/asaas-financial.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/azure-identity.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/clerk-auth.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/resend-email.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/quality}/code-analyzer.md +0 -0
|
@@ -1,426 +1,426 @@
|
|
|
1
|
-
# Deploy Checklist & Scripts
|
|
2
|
-
|
|
3
|
-
> Guia completo para deploy seguro em Azure.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Pre-Deploy Checklist
|
|
8
|
-
|
|
9
|
-
### 1. Código
|
|
10
|
-
|
|
11
|
-
- [ ] Build passa sem erros: `dotnet build`
|
|
12
|
-
- [ ] Testes passando: `dotnet test`
|
|
13
|
-
- [ ] Sem warnings críticos de segurança
|
|
14
|
-
- [ ] Code review aprovado (se aplicável)
|
|
15
|
-
|
|
16
|
-
### 2. Packages
|
|
17
|
-
|
|
18
|
-
- [ ] Sem conflitos de versão (NU1605/NU1608)
|
|
19
|
-
- [ ] `Azure.Identity` especificado explicitamente:
|
|
20
|
-
```xml
|
|
21
|
-
<PackageReference Include="Azure.Identity" Version="1.14.2" />
|
|
22
|
-
```
|
|
23
|
-
- [ ] Packages atualizados para versões estáveis
|
|
24
|
-
|
|
25
|
-
### 3. EF Core Migrations
|
|
26
|
-
|
|
27
|
-
- [ ] Sem pending model changes:
|
|
28
|
-
```bash
|
|
29
|
-
dotnet ef migrations has-pending-model-changes \
|
|
30
|
-
--project src/Infrastructure \
|
|
31
|
-
--startup-project src/Web
|
|
32
|
-
```
|
|
33
|
-
- [ ] Migration criada se necessário:
|
|
34
|
-
```bash
|
|
35
|
-
dotnet ef migrations add <Name> \
|
|
36
|
-
--project src/Infrastructure \
|
|
37
|
-
--startup-project src/Web
|
|
38
|
-
```
|
|
39
|
-
- [ ] Script SQL gerado e revisado:
|
|
40
|
-
```bash
|
|
41
|
-
dotnet ef migrations script --idempotent -o migration.sql
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### 4. Blazor .NET 10 (se aplicável)
|
|
45
|
-
|
|
46
|
-
- [ ] `.csproj` contém:
|
|
47
|
-
```xml
|
|
48
|
-
<RequiresAspNetWebAssets>true</RequiresAspNetWebAssets>
|
|
49
|
-
```
|
|
50
|
-
- [ ] Static assets funcionam localmente
|
|
51
|
-
|
|
52
|
-
### 5. Docker/Container (se Container Apps)
|
|
53
|
-
|
|
54
|
-
- [ ] Dockerfile válido
|
|
55
|
-
- [ ] Build funciona:
|
|
56
|
-
```bash
|
|
57
|
-
docker build --no-cache -t myapp:test .
|
|
58
|
-
```
|
|
59
|
-
- [ ] Container roda localmente:
|
|
60
|
-
```bash
|
|
61
|
-
docker run -p 8080:8080 myapp:test
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### 6. Infraestrutura Azure
|
|
65
|
-
|
|
66
|
-
- [ ] Bicep válido:
|
|
67
|
-
```bash
|
|
68
|
-
az bicep build --file infra/main.bicep
|
|
69
|
-
```
|
|
70
|
-
- [ ] Key Vault configurado
|
|
71
|
-
- [ ] Managed Identity habilitada
|
|
72
|
-
- [ ] Connection strings em Key Vault (não hardcoded)
|
|
73
|
-
|
|
74
|
-
### 7. Segurança
|
|
75
|
-
|
|
76
|
-
- [ ] Sem secrets em `appsettings.json`:
|
|
77
|
-
```bash
|
|
78
|
-
grep -rE "(Password=|Pwd=|Secret=)" appsettings*.json | grep -v Development
|
|
79
|
-
```
|
|
80
|
-
- [ ] HTTPS enforçado
|
|
81
|
-
- [ ] CORS configurado
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Scripts de Deploy
|
|
86
|
-
|
|
87
|
-
### Script Completo - Container Apps
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
#!/bin/bash
|
|
91
|
-
# deploy-container-app.sh
|
|
92
|
-
# Usage: ./deploy-container-app.sh [dev|staging|prod]
|
|
93
|
-
|
|
94
|
-
set -e
|
|
95
|
-
|
|
96
|
-
ENV="${1:-staging}"
|
|
97
|
-
PROJECT_NAME="myapp"
|
|
98
|
-
|
|
99
|
-
# Configurações por ambiente
|
|
100
|
-
case $ENV in
|
|
101
|
-
dev)
|
|
102
|
-
RG_NAME="rg-${PROJECT_NAME}-dev"
|
|
103
|
-
APP_NAME="ca-${PROJECT_NAME}-dev"
|
|
104
|
-
ACR_NAME="acr${PROJECT_NAME}dev"
|
|
105
|
-
;;
|
|
106
|
-
staging)
|
|
107
|
-
RG_NAME="rg-${PROJECT_NAME}-stg"
|
|
108
|
-
APP_NAME="ca-${PROJECT_NAME}-stg"
|
|
109
|
-
ACR_NAME="acr${PROJECT_NAME}stg"
|
|
110
|
-
;;
|
|
111
|
-
prod)
|
|
112
|
-
RG_NAME="rg-${PROJECT_NAME}-prod"
|
|
113
|
-
APP_NAME="ca-${PROJECT_NAME}-prod"
|
|
114
|
-
ACR_NAME="acr${PROJECT_NAME}prod"
|
|
115
|
-
;;
|
|
116
|
-
*)
|
|
117
|
-
echo "Ambiente inválido: $ENV"
|
|
118
|
-
exit 1
|
|
119
|
-
;;
|
|
120
|
-
esac
|
|
121
|
-
|
|
122
|
-
IMAGE_TAG="${GITHUB_SHA:-$(git rev-parse --short HEAD)}"
|
|
123
|
-
|
|
124
|
-
echo "🚀 Deploying to $ENV environment..."
|
|
125
|
-
echo " Resource Group: $RG_NAME"
|
|
126
|
-
echo " Container App: $APP_NAME"
|
|
127
|
-
echo " Image Tag: $IMAGE_TAG"
|
|
128
|
-
|
|
129
|
-
# 1. Pre-flight checks
|
|
130
|
-
echo "📋 Running pre-flight checks..."
|
|
131
|
-
|
|
132
|
-
# Check pending migrations
|
|
133
|
-
if ! dotnet ef migrations has-pending-model-changes \
|
|
134
|
-
--project src/Infrastructure \
|
|
135
|
-
--startup-project src/Web 2>/dev/null; then
|
|
136
|
-
echo "⚠️ Warning: Pending model changes detected"
|
|
137
|
-
read -p "Continue anyway? (y/N) " -n 1 -r
|
|
138
|
-
echo
|
|
139
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
140
|
-
exit 1
|
|
141
|
-
fi
|
|
142
|
-
fi
|
|
143
|
-
|
|
144
|
-
# 2. Build Docker image
|
|
145
|
-
echo "🐳 Building Docker image..."
|
|
146
|
-
docker build --no-cache -t ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG} .
|
|
147
|
-
docker tag ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG} \
|
|
148
|
-
${ACR_NAME}.azurecr.io/${PROJECT_NAME}:latest
|
|
149
|
-
|
|
150
|
-
# 3. Push to ACR
|
|
151
|
-
echo "📤 Pushing to ACR..."
|
|
152
|
-
az acr login --name $ACR_NAME
|
|
153
|
-
docker push ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG}
|
|
154
|
-
docker push ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:latest
|
|
155
|
-
|
|
156
|
-
# 4. Update Container App (with timestamp to force new revision)
|
|
157
|
-
echo "🔄 Updating Container App..."
|
|
158
|
-
az containerapp update \
|
|
159
|
-
--name $APP_NAME \
|
|
160
|
-
--resource-group $RG_NAME \
|
|
161
|
-
--image ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG} \
|
|
162
|
-
--set-env-vars "DEPLOY_TIMESTAMP=$(date +%s)"
|
|
163
|
-
|
|
164
|
-
# 5. Wait for deployment
|
|
165
|
-
echo "⏳ Waiting for deployment..."
|
|
166
|
-
sleep 10
|
|
167
|
-
|
|
168
|
-
# 6. Verify
|
|
169
|
-
echo "✅ Verifying deployment..."
|
|
170
|
-
STATUS=$(az containerapp show \
|
|
171
|
-
--name $APP_NAME \
|
|
172
|
-
--resource-group $RG_NAME \
|
|
173
|
-
--query "properties.runningStatus" -o tsv)
|
|
174
|
-
|
|
175
|
-
if [ "$STATUS" == "Running" ]; then
|
|
176
|
-
echo "✅ Deployment successful!"
|
|
177
|
-
FQDN=$(az containerapp show \
|
|
178
|
-
--name $APP_NAME \
|
|
179
|
-
--resource-group $RG_NAME \
|
|
180
|
-
--query "properties.configuration.ingress.fqdn" -o tsv)
|
|
181
|
-
echo "🌐 URL: https://$FQDN"
|
|
182
|
-
else
|
|
183
|
-
echo "❌ Deployment failed! Status: $STATUS"
|
|
184
|
-
echo "📋 Checking logs..."
|
|
185
|
-
az containerapp logs show \
|
|
186
|
-
--name $APP_NAME \
|
|
187
|
-
--resource-group $RG_NAME \
|
|
188
|
-
--tail 50
|
|
189
|
-
exit 1
|
|
190
|
-
fi
|
|
191
|
-
|
|
192
|
-
# 7. Health check
|
|
193
|
-
echo "🏥 Running health check..."
|
|
194
|
-
HEALTH_URL="https://$FQDN/health"
|
|
195
|
-
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL || echo "000")
|
|
196
|
-
|
|
197
|
-
if [ "$HTTP_CODE" == "200" ]; then
|
|
198
|
-
echo "✅ Health check passed!"
|
|
199
|
-
else
|
|
200
|
-
echo "⚠️ Health check returned: $HTTP_CODE"
|
|
201
|
-
fi
|
|
202
|
-
|
|
203
|
-
echo ""
|
|
204
|
-
echo "🎉 Deploy complete!"
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Script Verificação Pré-Deploy
|
|
208
|
-
|
|
209
|
-
```bash
|
|
210
|
-
#!/bin/bash
|
|
211
|
-
# preflight-check.sh
|
|
212
|
-
# Valida projeto antes de deploy
|
|
213
|
-
|
|
214
|
-
set -e
|
|
215
|
-
|
|
216
|
-
echo "🔍 MORPH Pre-Flight Check"
|
|
217
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
218
|
-
|
|
219
|
-
ERRORS=0
|
|
220
|
-
WARNINGS=0
|
|
221
|
-
|
|
222
|
-
# 1. Package conflicts
|
|
223
|
-
echo -n "📦 Checking packages... "
|
|
224
|
-
if dotnet restore 2>&1 | grep -qE "NU1605|NU1608"; then
|
|
225
|
-
echo "❌ Version conflicts detected"
|
|
226
|
-
((ERRORS++))
|
|
227
|
-
else
|
|
228
|
-
echo "✅"
|
|
229
|
-
fi
|
|
230
|
-
|
|
231
|
-
# 2. Pending migrations
|
|
232
|
-
echo -n "🗄️ Checking migrations... "
|
|
233
|
-
if ! dotnet ef migrations has-pending-model-changes \
|
|
234
|
-
--project src/Infrastructure \
|
|
235
|
-
--startup-project src/Web 2>/dev/null; then
|
|
236
|
-
echo "❌ Pending changes"
|
|
237
|
-
((ERRORS++))
|
|
238
|
-
else
|
|
239
|
-
echo "✅"
|
|
240
|
-
fi
|
|
241
|
-
|
|
242
|
-
# 3. Build
|
|
243
|
-
echo -n "🔨 Checking build... "
|
|
244
|
-
if ! dotnet build --nologo -v q 2>/dev/null; then
|
|
245
|
-
echo "❌ Build failed"
|
|
246
|
-
((ERRORS++))
|
|
247
|
-
else
|
|
248
|
-
echo "✅"
|
|
249
|
-
fi
|
|
250
|
-
|
|
251
|
-
# 4. Blazor assets (.NET 10)
|
|
252
|
-
echo -n "🎨 Checking Blazor assets... "
|
|
253
|
-
if grep -q "net10.0" *.csproj 2>/dev/null; then
|
|
254
|
-
if ! grep -q "RequiresAspNetWebAssets.*true" *.csproj 2>/dev/null; then
|
|
255
|
-
echo "❌ Missing RequiresAspNetWebAssets"
|
|
256
|
-
((ERRORS++))
|
|
257
|
-
else
|
|
258
|
-
echo "✅"
|
|
259
|
-
fi
|
|
260
|
-
else
|
|
261
|
-
echo "⏭️ Not .NET 10"
|
|
262
|
-
fi
|
|
263
|
-
|
|
264
|
-
# 5. Bicep
|
|
265
|
-
echo -n "📐 Checking Bicep... "
|
|
266
|
-
if [ -f "infra/main.bicep" ]; then
|
|
267
|
-
if ! az bicep build --file infra/main.bicep --stdout >/dev/null 2>&1; then
|
|
268
|
-
echo "❌ Syntax errors"
|
|
269
|
-
((ERRORS++))
|
|
270
|
-
else
|
|
271
|
-
echo "✅"
|
|
272
|
-
fi
|
|
273
|
-
else
|
|
274
|
-
echo "⏭️ No Bicep files"
|
|
275
|
-
fi
|
|
276
|
-
|
|
277
|
-
# 6. Secrets scan
|
|
278
|
-
echo -n "🔐 Checking secrets... "
|
|
279
|
-
if grep -rE "(Password=|Pwd=|Secret=)" appsettings*.json 2>/dev/null | grep -v Development; then
|
|
280
|
-
echo "⚠️ Secrets in config"
|
|
281
|
-
((WARNINGS++))
|
|
282
|
-
else
|
|
283
|
-
echo "✅"
|
|
284
|
-
fi
|
|
285
|
-
|
|
286
|
-
# Summary
|
|
287
|
-
echo ""
|
|
288
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
289
|
-
if [ $ERRORS -eq 0 ]; then
|
|
290
|
-
if [ $WARNINGS -eq 0 ]; then
|
|
291
|
-
echo "✅ All checks passed!"
|
|
292
|
-
else
|
|
293
|
-
echo "⚠️ $WARNINGS warning(s), but OK to deploy"
|
|
294
|
-
fi
|
|
295
|
-
exit 0
|
|
296
|
-
else
|
|
297
|
-
echo "❌ $ERRORS error(s) found. Fix before deploy!"
|
|
298
|
-
exit 1
|
|
299
|
-
fi
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## Troubleshooting Deploy
|
|
305
|
-
|
|
306
|
-
### Container App não atualiza
|
|
307
|
-
|
|
308
|
-
**Sintoma:** Após push, Container App continua com versão antiga.
|
|
309
|
-
|
|
310
|
-
**Causa:** Mesmo digest de imagem não triggera nova revisão.
|
|
311
|
-
|
|
312
|
-
**Solução:**
|
|
313
|
-
```bash
|
|
314
|
-
az containerapp update \
|
|
315
|
-
--name $APP_NAME \
|
|
316
|
-
--resource-group $RG_NAME \
|
|
317
|
-
--set-env-vars "DEPLOY_TIMESTAMP=$(date +%s)"
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### blazor.web.js 404
|
|
321
|
-
|
|
322
|
-
**Sintoma:** Página Blazor não carrega.
|
|
323
|
-
|
|
324
|
-
**Solução:** Adicionar ao `.csproj`:
|
|
325
|
-
```xml
|
|
326
|
-
<RequiresAspNetWebAssets>true</RequiresAspNetWebAssets>
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Managed Identity não funciona
|
|
330
|
-
|
|
331
|
-
**Sintoma:** Acesso negado a Key Vault ou outros recursos.
|
|
332
|
-
|
|
333
|
-
**Verificar:**
|
|
334
|
-
1. Identity habilitada no Container App
|
|
335
|
-
2. RBAC atribuída (Key Vault Secrets User, etc.)
|
|
336
|
-
3. Aguardar 5-10 min após atribuição
|
|
337
|
-
|
|
338
|
-
```bash
|
|
339
|
-
# Verificar identity
|
|
340
|
-
az containerapp identity show \
|
|
341
|
-
--name $APP_NAME \
|
|
342
|
-
--resource-group $RG_NAME
|
|
343
|
-
|
|
344
|
-
# Verificar RBAC
|
|
345
|
-
az role assignment list \
|
|
346
|
-
--assignee <IDENTITY_PRINCIPAL_ID> \
|
|
347
|
-
--scope <KEY_VAULT_ID>
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
### DefaultAzureCredential lento
|
|
351
|
-
|
|
352
|
-
**Sintoma:** Startup demora 30+ segundos.
|
|
353
|
-
|
|
354
|
-
**Solução:** Desabilitar credenciais não usadas (ver azure.md).
|
|
355
|
-
|
|
356
|
-
### Migrations não aplicadas
|
|
357
|
-
|
|
358
|
-
**Sintoma:** `Invalid object name 'TableName'`
|
|
359
|
-
|
|
360
|
-
**Solução:**
|
|
361
|
-
```bash
|
|
362
|
-
# Opção 1: Rodar migration no pipeline
|
|
363
|
-
dotnet ef database update
|
|
364
|
-
|
|
365
|
-
# Opção 2: Auto-migrate no startup (dev/staging only)
|
|
366
|
-
app.Services.CreateScope().ServiceProvider
|
|
367
|
-
.GetRequiredService<AppDbContext>()
|
|
368
|
-
.Database.Migrate();
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
---
|
|
372
|
-
|
|
373
|
-
## Logs e Debugging
|
|
374
|
-
|
|
375
|
-
### Container Apps Logs
|
|
376
|
-
|
|
377
|
-
```bash
|
|
378
|
-
# Logs em tempo real
|
|
379
|
-
az containerapp logs show \
|
|
380
|
-
--name $APP_NAME \
|
|
381
|
-
--resource-group $RG_NAME \
|
|
382
|
-
--follow
|
|
383
|
-
|
|
384
|
-
# Últimas 100 linhas
|
|
385
|
-
az containerapp logs show \
|
|
386
|
-
--name $APP_NAME \
|
|
387
|
-
--resource-group $RG_NAME \
|
|
388
|
-
--tail 100
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
### Application Insights
|
|
392
|
-
|
|
393
|
-
```bash
|
|
394
|
-
# Query de exceptions
|
|
395
|
-
az monitor app-insights query \
|
|
396
|
-
--app $APPINSIGHTS_NAME \
|
|
397
|
-
--analytics-query "exceptions | take 10"
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
### Container App Status
|
|
401
|
-
|
|
402
|
-
```bash
|
|
403
|
-
# Status geral
|
|
404
|
-
az containerapp show \
|
|
405
|
-
--name $APP_NAME \
|
|
406
|
-
--resource-group $RG_NAME \
|
|
407
|
-
--query "{status:properties.runningStatus,replicas:properties.template.scale}"
|
|
408
|
-
|
|
409
|
-
# Revisões
|
|
410
|
-
az containerapp revision list \
|
|
411
|
-
--name $APP_NAME \
|
|
412
|
-
--resource-group $RG_NAME \
|
|
413
|
-
--query "[].{name:name,active:properties.active,traffic:properties.trafficWeight}"
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
## Referências
|
|
419
|
-
|
|
420
|
-
- [azure.md](../../standards/azure.md) - Padrões Azure
|
|
421
|
-
- [morph-preflight.md](../../../.claude/commands/morph-preflight.md) - Comando de validação
|
|
422
|
-
- [blazor-efcore.md](../../../../framework/standards/blazor-efcore.md) - EF Core patterns
|
|
423
|
-
|
|
424
|
-
---
|
|
425
|
-
|
|
426
|
-
*MORPH-SPEC by Polymorphism Tech*
|
|
1
|
+
# Deploy Checklist & Scripts
|
|
2
|
+
|
|
3
|
+
> Guia completo para deploy seguro em Azure.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Pre-Deploy Checklist
|
|
8
|
+
|
|
9
|
+
### 1. Código
|
|
10
|
+
|
|
11
|
+
- [ ] Build passa sem erros: `dotnet build`
|
|
12
|
+
- [ ] Testes passando: `dotnet test`
|
|
13
|
+
- [ ] Sem warnings críticos de segurança
|
|
14
|
+
- [ ] Code review aprovado (se aplicável)
|
|
15
|
+
|
|
16
|
+
### 2. Packages
|
|
17
|
+
|
|
18
|
+
- [ ] Sem conflitos de versão (NU1605/NU1608)
|
|
19
|
+
- [ ] `Azure.Identity` especificado explicitamente:
|
|
20
|
+
```xml
|
|
21
|
+
<PackageReference Include="Azure.Identity" Version="1.14.2" />
|
|
22
|
+
```
|
|
23
|
+
- [ ] Packages atualizados para versões estáveis
|
|
24
|
+
|
|
25
|
+
### 3. EF Core Migrations
|
|
26
|
+
|
|
27
|
+
- [ ] Sem pending model changes:
|
|
28
|
+
```bash
|
|
29
|
+
dotnet ef migrations has-pending-model-changes \
|
|
30
|
+
--project src/Infrastructure \
|
|
31
|
+
--startup-project src/Web
|
|
32
|
+
```
|
|
33
|
+
- [ ] Migration criada se necessário:
|
|
34
|
+
```bash
|
|
35
|
+
dotnet ef migrations add <Name> \
|
|
36
|
+
--project src/Infrastructure \
|
|
37
|
+
--startup-project src/Web
|
|
38
|
+
```
|
|
39
|
+
- [ ] Script SQL gerado e revisado:
|
|
40
|
+
```bash
|
|
41
|
+
dotnet ef migrations script --idempotent -o migration.sql
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 4. Blazor .NET 10 (se aplicável)
|
|
45
|
+
|
|
46
|
+
- [ ] `.csproj` contém:
|
|
47
|
+
```xml
|
|
48
|
+
<RequiresAspNetWebAssets>true</RequiresAspNetWebAssets>
|
|
49
|
+
```
|
|
50
|
+
- [ ] Static assets funcionam localmente
|
|
51
|
+
|
|
52
|
+
### 5. Docker/Container (se Container Apps)
|
|
53
|
+
|
|
54
|
+
- [ ] Dockerfile válido
|
|
55
|
+
- [ ] Build funciona:
|
|
56
|
+
```bash
|
|
57
|
+
docker build --no-cache -t myapp:test .
|
|
58
|
+
```
|
|
59
|
+
- [ ] Container roda localmente:
|
|
60
|
+
```bash
|
|
61
|
+
docker run -p 8080:8080 myapp:test
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 6. Infraestrutura Azure
|
|
65
|
+
|
|
66
|
+
- [ ] Bicep válido:
|
|
67
|
+
```bash
|
|
68
|
+
az bicep build --file infra/main.bicep
|
|
69
|
+
```
|
|
70
|
+
- [ ] Key Vault configurado
|
|
71
|
+
- [ ] Managed Identity habilitada
|
|
72
|
+
- [ ] Connection strings em Key Vault (não hardcoded)
|
|
73
|
+
|
|
74
|
+
### 7. Segurança
|
|
75
|
+
|
|
76
|
+
- [ ] Sem secrets em `appsettings.json`:
|
|
77
|
+
```bash
|
|
78
|
+
grep -rE "(Password=|Pwd=|Secret=)" appsettings*.json | grep -v Development
|
|
79
|
+
```
|
|
80
|
+
- [ ] HTTPS enforçado
|
|
81
|
+
- [ ] CORS configurado
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Scripts de Deploy
|
|
86
|
+
|
|
87
|
+
### Script Completo - Container Apps
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
#!/bin/bash
|
|
91
|
+
# deploy-container-app.sh
|
|
92
|
+
# Usage: ./deploy-container-app.sh [dev|staging|prod]
|
|
93
|
+
|
|
94
|
+
set -e
|
|
95
|
+
|
|
96
|
+
ENV="${1:-staging}"
|
|
97
|
+
PROJECT_NAME="myapp"
|
|
98
|
+
|
|
99
|
+
# Configurações por ambiente
|
|
100
|
+
case $ENV in
|
|
101
|
+
dev)
|
|
102
|
+
RG_NAME="rg-${PROJECT_NAME}-dev"
|
|
103
|
+
APP_NAME="ca-${PROJECT_NAME}-dev"
|
|
104
|
+
ACR_NAME="acr${PROJECT_NAME}dev"
|
|
105
|
+
;;
|
|
106
|
+
staging)
|
|
107
|
+
RG_NAME="rg-${PROJECT_NAME}-stg"
|
|
108
|
+
APP_NAME="ca-${PROJECT_NAME}-stg"
|
|
109
|
+
ACR_NAME="acr${PROJECT_NAME}stg"
|
|
110
|
+
;;
|
|
111
|
+
prod)
|
|
112
|
+
RG_NAME="rg-${PROJECT_NAME}-prod"
|
|
113
|
+
APP_NAME="ca-${PROJECT_NAME}-prod"
|
|
114
|
+
ACR_NAME="acr${PROJECT_NAME}prod"
|
|
115
|
+
;;
|
|
116
|
+
*)
|
|
117
|
+
echo "Ambiente inválido: $ENV"
|
|
118
|
+
exit 1
|
|
119
|
+
;;
|
|
120
|
+
esac
|
|
121
|
+
|
|
122
|
+
IMAGE_TAG="${GITHUB_SHA:-$(git rev-parse --short HEAD)}"
|
|
123
|
+
|
|
124
|
+
echo "🚀 Deploying to $ENV environment..."
|
|
125
|
+
echo " Resource Group: $RG_NAME"
|
|
126
|
+
echo " Container App: $APP_NAME"
|
|
127
|
+
echo " Image Tag: $IMAGE_TAG"
|
|
128
|
+
|
|
129
|
+
# 1. Pre-flight checks
|
|
130
|
+
echo "📋 Running pre-flight checks..."
|
|
131
|
+
|
|
132
|
+
# Check pending migrations
|
|
133
|
+
if ! dotnet ef migrations has-pending-model-changes \
|
|
134
|
+
--project src/Infrastructure \
|
|
135
|
+
--startup-project src/Web 2>/dev/null; then
|
|
136
|
+
echo "⚠️ Warning: Pending model changes detected"
|
|
137
|
+
read -p "Continue anyway? (y/N) " -n 1 -r
|
|
138
|
+
echo
|
|
139
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
140
|
+
exit 1
|
|
141
|
+
fi
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# 2. Build Docker image
|
|
145
|
+
echo "🐳 Building Docker image..."
|
|
146
|
+
docker build --no-cache -t ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG} .
|
|
147
|
+
docker tag ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG} \
|
|
148
|
+
${ACR_NAME}.azurecr.io/${PROJECT_NAME}:latest
|
|
149
|
+
|
|
150
|
+
# 3. Push to ACR
|
|
151
|
+
echo "📤 Pushing to ACR..."
|
|
152
|
+
az acr login --name $ACR_NAME
|
|
153
|
+
docker push ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG}
|
|
154
|
+
docker push ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:latest
|
|
155
|
+
|
|
156
|
+
# 4. Update Container App (with timestamp to force new revision)
|
|
157
|
+
echo "🔄 Updating Container App..."
|
|
158
|
+
az containerapp update \
|
|
159
|
+
--name $APP_NAME \
|
|
160
|
+
--resource-group $RG_NAME \
|
|
161
|
+
--image ${ACR_NAME}.azurecr.io/${PROJECT_NAME}:${IMAGE_TAG} \
|
|
162
|
+
--set-env-vars "DEPLOY_TIMESTAMP=$(date +%s)"
|
|
163
|
+
|
|
164
|
+
# 5. Wait for deployment
|
|
165
|
+
echo "⏳ Waiting for deployment..."
|
|
166
|
+
sleep 10
|
|
167
|
+
|
|
168
|
+
# 6. Verify
|
|
169
|
+
echo "✅ Verifying deployment..."
|
|
170
|
+
STATUS=$(az containerapp show \
|
|
171
|
+
--name $APP_NAME \
|
|
172
|
+
--resource-group $RG_NAME \
|
|
173
|
+
--query "properties.runningStatus" -o tsv)
|
|
174
|
+
|
|
175
|
+
if [ "$STATUS" == "Running" ]; then
|
|
176
|
+
echo "✅ Deployment successful!"
|
|
177
|
+
FQDN=$(az containerapp show \
|
|
178
|
+
--name $APP_NAME \
|
|
179
|
+
--resource-group $RG_NAME \
|
|
180
|
+
--query "properties.configuration.ingress.fqdn" -o tsv)
|
|
181
|
+
echo "🌐 URL: https://$FQDN"
|
|
182
|
+
else
|
|
183
|
+
echo "❌ Deployment failed! Status: $STATUS"
|
|
184
|
+
echo "📋 Checking logs..."
|
|
185
|
+
az containerapp logs show \
|
|
186
|
+
--name $APP_NAME \
|
|
187
|
+
--resource-group $RG_NAME \
|
|
188
|
+
--tail 50
|
|
189
|
+
exit 1
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# 7. Health check
|
|
193
|
+
echo "🏥 Running health check..."
|
|
194
|
+
HEALTH_URL="https://$FQDN/health"
|
|
195
|
+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL || echo "000")
|
|
196
|
+
|
|
197
|
+
if [ "$HTTP_CODE" == "200" ]; then
|
|
198
|
+
echo "✅ Health check passed!"
|
|
199
|
+
else
|
|
200
|
+
echo "⚠️ Health check returned: $HTTP_CODE"
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
echo ""
|
|
204
|
+
echo "🎉 Deploy complete!"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Script Verificação Pré-Deploy
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
#!/bin/bash
|
|
211
|
+
# preflight-check.sh
|
|
212
|
+
# Valida projeto antes de deploy
|
|
213
|
+
|
|
214
|
+
set -e
|
|
215
|
+
|
|
216
|
+
echo "🔍 MORPH Pre-Flight Check"
|
|
217
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
218
|
+
|
|
219
|
+
ERRORS=0
|
|
220
|
+
WARNINGS=0
|
|
221
|
+
|
|
222
|
+
# 1. Package conflicts
|
|
223
|
+
echo -n "📦 Checking packages... "
|
|
224
|
+
if dotnet restore 2>&1 | grep -qE "NU1605|NU1608"; then
|
|
225
|
+
echo "❌ Version conflicts detected"
|
|
226
|
+
((ERRORS++))
|
|
227
|
+
else
|
|
228
|
+
echo "✅"
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# 2. Pending migrations
|
|
232
|
+
echo -n "🗄️ Checking migrations... "
|
|
233
|
+
if ! dotnet ef migrations has-pending-model-changes \
|
|
234
|
+
--project src/Infrastructure \
|
|
235
|
+
--startup-project src/Web 2>/dev/null; then
|
|
236
|
+
echo "❌ Pending changes"
|
|
237
|
+
((ERRORS++))
|
|
238
|
+
else
|
|
239
|
+
echo "✅"
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
# 3. Build
|
|
243
|
+
echo -n "🔨 Checking build... "
|
|
244
|
+
if ! dotnet build --nologo -v q 2>/dev/null; then
|
|
245
|
+
echo "❌ Build failed"
|
|
246
|
+
((ERRORS++))
|
|
247
|
+
else
|
|
248
|
+
echo "✅"
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# 4. Blazor assets (.NET 10)
|
|
252
|
+
echo -n "🎨 Checking Blazor assets... "
|
|
253
|
+
if grep -q "net10.0" *.csproj 2>/dev/null; then
|
|
254
|
+
if ! grep -q "RequiresAspNetWebAssets.*true" *.csproj 2>/dev/null; then
|
|
255
|
+
echo "❌ Missing RequiresAspNetWebAssets"
|
|
256
|
+
((ERRORS++))
|
|
257
|
+
else
|
|
258
|
+
echo "✅"
|
|
259
|
+
fi
|
|
260
|
+
else
|
|
261
|
+
echo "⏭️ Not .NET 10"
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
# 5. Bicep
|
|
265
|
+
echo -n "📐 Checking Bicep... "
|
|
266
|
+
if [ -f "infra/main.bicep" ]; then
|
|
267
|
+
if ! az bicep build --file infra/main.bicep --stdout >/dev/null 2>&1; then
|
|
268
|
+
echo "❌ Syntax errors"
|
|
269
|
+
((ERRORS++))
|
|
270
|
+
else
|
|
271
|
+
echo "✅"
|
|
272
|
+
fi
|
|
273
|
+
else
|
|
274
|
+
echo "⏭️ No Bicep files"
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# 6. Secrets scan
|
|
278
|
+
echo -n "🔐 Checking secrets... "
|
|
279
|
+
if grep -rE "(Password=|Pwd=|Secret=)" appsettings*.json 2>/dev/null | grep -v Development; then
|
|
280
|
+
echo "⚠️ Secrets in config"
|
|
281
|
+
((WARNINGS++))
|
|
282
|
+
else
|
|
283
|
+
echo "✅"
|
|
284
|
+
fi
|
|
285
|
+
|
|
286
|
+
# Summary
|
|
287
|
+
echo ""
|
|
288
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
289
|
+
if [ $ERRORS -eq 0 ]; then
|
|
290
|
+
if [ $WARNINGS -eq 0 ]; then
|
|
291
|
+
echo "✅ All checks passed!"
|
|
292
|
+
else
|
|
293
|
+
echo "⚠️ $WARNINGS warning(s), but OK to deploy"
|
|
294
|
+
fi
|
|
295
|
+
exit 0
|
|
296
|
+
else
|
|
297
|
+
echo "❌ $ERRORS error(s) found. Fix before deploy!"
|
|
298
|
+
exit 1
|
|
299
|
+
fi
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Troubleshooting Deploy
|
|
305
|
+
|
|
306
|
+
### Container App não atualiza
|
|
307
|
+
|
|
308
|
+
**Sintoma:** Após push, Container App continua com versão antiga.
|
|
309
|
+
|
|
310
|
+
**Causa:** Mesmo digest de imagem não triggera nova revisão.
|
|
311
|
+
|
|
312
|
+
**Solução:**
|
|
313
|
+
```bash
|
|
314
|
+
az containerapp update \
|
|
315
|
+
--name $APP_NAME \
|
|
316
|
+
--resource-group $RG_NAME \
|
|
317
|
+
--set-env-vars "DEPLOY_TIMESTAMP=$(date +%s)"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### blazor.web.js 404
|
|
321
|
+
|
|
322
|
+
**Sintoma:** Página Blazor não carrega.
|
|
323
|
+
|
|
324
|
+
**Solução:** Adicionar ao `.csproj`:
|
|
325
|
+
```xml
|
|
326
|
+
<RequiresAspNetWebAssets>true</RequiresAspNetWebAssets>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Managed Identity não funciona
|
|
330
|
+
|
|
331
|
+
**Sintoma:** Acesso negado a Key Vault ou outros recursos.
|
|
332
|
+
|
|
333
|
+
**Verificar:**
|
|
334
|
+
1. Identity habilitada no Container App
|
|
335
|
+
2. RBAC atribuída (Key Vault Secrets User, etc.)
|
|
336
|
+
3. Aguardar 5-10 min após atribuição
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# Verificar identity
|
|
340
|
+
az containerapp identity show \
|
|
341
|
+
--name $APP_NAME \
|
|
342
|
+
--resource-group $RG_NAME
|
|
343
|
+
|
|
344
|
+
# Verificar RBAC
|
|
345
|
+
az role assignment list \
|
|
346
|
+
--assignee <IDENTITY_PRINCIPAL_ID> \
|
|
347
|
+
--scope <KEY_VAULT_ID>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### DefaultAzureCredential lento
|
|
351
|
+
|
|
352
|
+
**Sintoma:** Startup demora 30+ segundos.
|
|
353
|
+
|
|
354
|
+
**Solução:** Desabilitar credenciais não usadas (ver azure.md).
|
|
355
|
+
|
|
356
|
+
### Migrations não aplicadas
|
|
357
|
+
|
|
358
|
+
**Sintoma:** `Invalid object name 'TableName'`
|
|
359
|
+
|
|
360
|
+
**Solução:**
|
|
361
|
+
```bash
|
|
362
|
+
# Opção 1: Rodar migration no pipeline
|
|
363
|
+
dotnet ef database update
|
|
364
|
+
|
|
365
|
+
# Opção 2: Auto-migrate no startup (dev/staging only)
|
|
366
|
+
app.Services.CreateScope().ServiceProvider
|
|
367
|
+
.GetRequiredService<AppDbContext>()
|
|
368
|
+
.Database.Migrate();
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## Logs e Debugging
|
|
374
|
+
|
|
375
|
+
### Container Apps Logs
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
# Logs em tempo real
|
|
379
|
+
az containerapp logs show \
|
|
380
|
+
--name $APP_NAME \
|
|
381
|
+
--resource-group $RG_NAME \
|
|
382
|
+
--follow
|
|
383
|
+
|
|
384
|
+
# Últimas 100 linhas
|
|
385
|
+
az containerapp logs show \
|
|
386
|
+
--name $APP_NAME \
|
|
387
|
+
--resource-group $RG_NAME \
|
|
388
|
+
--tail 100
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Application Insights
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
# Query de exceptions
|
|
395
|
+
az monitor app-insights query \
|
|
396
|
+
--app $APPINSIGHTS_NAME \
|
|
397
|
+
--analytics-query "exceptions | take 10"
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Container App Status
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# Status geral
|
|
404
|
+
az containerapp show \
|
|
405
|
+
--name $APP_NAME \
|
|
406
|
+
--resource-group $RG_NAME \
|
|
407
|
+
--query "{status:properties.runningStatus,replicas:properties.template.scale}"
|
|
408
|
+
|
|
409
|
+
# Revisões
|
|
410
|
+
az containerapp revision list \
|
|
411
|
+
--name $APP_NAME \
|
|
412
|
+
--resource-group $RG_NAME \
|
|
413
|
+
--query "[].{name:name,active:properties.active,traffic:properties.trafficWeight}"
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Referências
|
|
419
|
+
|
|
420
|
+
- [azure.md](../../standards/azure.md) - Padrões Azure
|
|
421
|
+
- [morph-preflight.md](../../../.claude/commands/morph-preflight.md) - Comando de validação
|
|
422
|
+
- [blazor-efcore.md](../../../../framework/standards/blazor-efcore.md) - EF Core patterns
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
*MORPH-SPEC by Polymorphism Tech*
|