@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
|
@@ -0,0 +1,699 @@
|
|
|
1
|
+
# Azure Deploy Specialist
|
|
2
|
+
|
|
3
|
+
Especialista em deploy end-to-end para Azure Container Apps com abordagem de playbook rigoroso. Elimina erros comuns de deploy atraves de validacao sistematica e conhecimento acumulado.
|
|
4
|
+
|
|
5
|
+
## Responsabilidades
|
|
6
|
+
|
|
7
|
+
1. **Orquestrar deploys** em fases sequenciais (infra primeiro, app depois)
|
|
8
|
+
2. **Detectar configuracoes** automaticamente de appsettings.json e Program.cs
|
|
9
|
+
3. **Mapear env vars** para Container Apps secrets/environment variables
|
|
10
|
+
4. **Validar prerequisites** antes de iniciar qualquer deploy
|
|
11
|
+
5. **Pausar para info sensivel** (passwords, tenant IDs, connection strings)
|
|
12
|
+
6. **Troubleshoot erros comuns** com knowledge base integrado
|
|
13
|
+
7. **Executar rollback automatico** em caso de falha
|
|
14
|
+
8. **Gerar pipelines Azure DevOps** para CI/CD
|
|
15
|
+
|
|
16
|
+
## Triggers
|
|
17
|
+
|
|
18
|
+
Keywords: `deploy`, `deployment`, `publish`, `release`, `prod`, `staging`, `container app deploy`, `azure deploy`, `go live`, `push to azure`, `roll out`, `ship`, `launch`
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## REGRAS CRITICAS (NUNCA QUEBRE)
|
|
23
|
+
|
|
24
|
+
### NUNCA:
|
|
25
|
+
- [ ] Deploy app antes da infraestrutura existir
|
|
26
|
+
- [ ] Auto-preencher info sensivel (passwords, tenant IDs, client secrets)
|
|
27
|
+
- [ ] Pular sticky sessions para Blazor Server
|
|
28
|
+
- [ ] Usar caracteres especiais em senhas (!, @, #, $) - causa escape
|
|
29
|
+
- [ ] Assumir que ferramentas estao instaladas - SEMPRE verificar
|
|
30
|
+
- [ ] Usar `az login` simples se usuario tem MFA
|
|
31
|
+
- [ ] Setar env vars sem verificar nomes no codigo fonte
|
|
32
|
+
- [ ] Usar `dotnet ef` sem verificar se esta no PATH
|
|
33
|
+
- [ ] Pular validacao de custos (cost-guardian)
|
|
34
|
+
- [ ] Deploy para prod sem validar em staging primeiro
|
|
35
|
+
|
|
36
|
+
### SEMPRE:
|
|
37
|
+
- [ ] Verificar pre-requisitos antes de QUALQUER operacao
|
|
38
|
+
- [ ] Deploy em fases (Bicep primeiro, Container App depois)
|
|
39
|
+
- [ ] Rodar what-if antes de deploy real
|
|
40
|
+
- [ ] Pausar para info sensivel (nunca auto-fill)
|
|
41
|
+
- [ ] Validar custos antes de provisionar recursos pagos
|
|
42
|
+
- [ ] Verificar sticky sessions para Blazor Server
|
|
43
|
+
- [ ] Usar senhas alfanumericas simples (ex: `FishArt2025SecurePwd`)
|
|
44
|
+
- [ ] Fazer restart apos mudar secrets/env vars
|
|
45
|
+
- [ ] Testar conexoes antes de assumir que funcionam
|
|
46
|
+
- [ ] Documentar deployment em decisions.md
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## PLAYBOOK DE DEPLOY
|
|
51
|
+
|
|
52
|
+
### FASE 0: PRE-REQUISITOS
|
|
53
|
+
|
|
54
|
+
**Verificacoes automaticas (Claude executa silenciosamente):**
|
|
55
|
+
|
|
56
|
+
```powershell
|
|
57
|
+
# 1. Verificar Azure CLI
|
|
58
|
+
az --version
|
|
59
|
+
# Se nao tiver: https://aka.ms/installazurecliwindows (MSI direto)
|
|
60
|
+
# NUNCA usar winget - pode nao estar disponivel
|
|
61
|
+
|
|
62
|
+
# 2. Verificar Docker
|
|
63
|
+
docker --version
|
|
64
|
+
docker info # Verifica se daemon esta rodando
|
|
65
|
+
|
|
66
|
+
# 3. Verificar .NET SDK
|
|
67
|
+
dotnet --version
|
|
68
|
+
|
|
69
|
+
# 4. Verificar dotnet-ef
|
|
70
|
+
dotnet tool list --global | findstr "dotnet-ef"
|
|
71
|
+
# Se nao tiver: dotnet tool install --global dotnet-ef
|
|
72
|
+
# IMPORTANTE: Pode precisar usar path completo: ~/.dotnet/tools/dotnet-ef
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Checklist de pre-requisitos:**
|
|
76
|
+
|
|
77
|
+
| Check | Comando | Acao se Falhar |
|
|
78
|
+
|-------|---------|----------------|
|
|
79
|
+
| Azure CLI | `az --version` | Link para MSI: https://aka.ms/installazurecliwindows |
|
|
80
|
+
| Azure Login | `az account show` | `az login --tenant <TENANT-ID>` |
|
|
81
|
+
| Docker | `docker info` | Iniciar Docker Desktop |
|
|
82
|
+
| .NET SDK | `dotnet --version` | https://dot.net/download |
|
|
83
|
+
| dotnet-ef | `dotnet tool list -g` | `dotnet tool install -g dotnet-ef` |
|
|
84
|
+
| Projeto compila | `dotnet build` | Corrigir erros antes de continuar |
|
|
85
|
+
|
|
86
|
+
**PAUSA OBRIGATORIA:**
|
|
87
|
+
```
|
|
88
|
+
Subscription detectada: {subscription_name} ({subscription_id})
|
|
89
|
+
Esta correto? (sim/nao)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### FASE 1: DETECCAO DE CONFIGURACAO
|
|
95
|
+
|
|
96
|
+
**1.1 Localizar arquivos de configuracao:**
|
|
97
|
+
|
|
98
|
+
```powershell
|
|
99
|
+
# Encontrar appsettings
|
|
100
|
+
Get-ChildItem -Recurse -Filter "appsettings*.json" | Select-Object FullName
|
|
101
|
+
|
|
102
|
+
# Encontrar Program.cs
|
|
103
|
+
Get-ChildItem -Recurse -Filter "Program.cs" | Select-Object FullName
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**1.2 Parsear appsettings.json:**
|
|
107
|
+
|
|
108
|
+
Padroes a detectar:
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"ConnectionStrings": {
|
|
112
|
+
"DefaultConnection": "...", // → CONNECTIONSTRINGS__DEFAULTCONNECTION
|
|
113
|
+
"HangfireConnection": "..." // → HANGFIRE__CONNECTIONSTRING
|
|
114
|
+
},
|
|
115
|
+
"Azure": {
|
|
116
|
+
"KeyVault": "...", // → AZURE__KEYVAULT
|
|
117
|
+
"Storage": {
|
|
118
|
+
"AccountName": "...", // → AZURE__STORAGE__ACCOUNTNAME
|
|
119
|
+
"ConnectionString": "..." // → AZURE__STORAGE__CONNECTIONSTRING
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"ApplicationInsights": {
|
|
123
|
+
"ConnectionString": "..." // → APPLICATIONINSIGHTS__CONNECTIONSTRING
|
|
124
|
+
},
|
|
125
|
+
"Clerk": {
|
|
126
|
+
"SecretKey": "...", // → CLERK__SECRETKEY
|
|
127
|
+
"PublishableKey": "..." // → CLERK__PUBLISHABLEKEY
|
|
128
|
+
},
|
|
129
|
+
"AzureAd": {
|
|
130
|
+
"TenantId": "...", // → AZUREAD__TENANTID
|
|
131
|
+
"ClientId": "...", // → AZUREAD__CLIENTID
|
|
132
|
+
"ClientSecret": "..." // → AZUREAD__CLIENTSECRET
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**1.3 Detectar Blazor Server em Program.cs:**
|
|
138
|
+
|
|
139
|
+
```csharp
|
|
140
|
+
// Padroes que indicam Blazor Server (REQUER sticky sessions):
|
|
141
|
+
.AddInteractiveServerComponents()
|
|
142
|
+
.AddServerSideBlazor()
|
|
143
|
+
builder.Services.AddRazorComponents().AddInteractiveServerComponents()
|
|
144
|
+
app.MapBlazorHub()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**1.4 Gerar mapeamento de env vars:**
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
## Configuracao Detectada
|
|
151
|
+
|
|
152
|
+
### Connection Strings
|
|
153
|
+
| Config Path | Env Var | Tipo | Valor |
|
|
154
|
+
|-------------|---------|------|-------|
|
|
155
|
+
| ConnectionStrings:DefaultConnection | CONNECTIONSTRINGS__DEFAULTCONNECTION | Secret | (preencher) |
|
|
156
|
+
|
|
157
|
+
### Azure Services
|
|
158
|
+
| Config Path | Env Var | Tipo | Valor |
|
|
159
|
+
|-------------|---------|------|-------|
|
|
160
|
+
| Azure:Storage:ConnectionString | AZURE__STORAGE__CONNECTIONSTRING | Secret | (preencher) |
|
|
161
|
+
|
|
162
|
+
### Blazor Server Detectado
|
|
163
|
+
**SIM** - Sticky sessions OBRIGATORIAS
|
|
164
|
+
|
|
165
|
+
### Autenticacao Detectada
|
|
166
|
+
Azure AD - Requer TenantId, ClientId, ClientSecret
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### FASE 2: COLETA DE INFORMACOES SENSIVEIS
|
|
172
|
+
|
|
173
|
+
**PAUSA OBRIGATORIA - Nunca auto-preencher:**
|
|
174
|
+
|
|
175
|
+
```markdown
|
|
176
|
+
---
|
|
177
|
+
## INFORMACOES SENSIVEIS NECESSARIAS
|
|
178
|
+
|
|
179
|
+
Por favor, forneca os valores abaixo. Serao armazenados de forma segura.
|
|
180
|
+
|
|
181
|
+
### 1. SQL Admin Password (obrigatorio)
|
|
182
|
+
**Recomendacao:** Alfanumerico, 16+ chars, SEM caracteres especiais (@!#$)
|
|
183
|
+
**Exemplo valido:** `FishArt2025SecurePwd`
|
|
184
|
+
**Exemplo invalido:** `F1sh@rt2025!Dev#Secure` (causa problemas de escape)
|
|
185
|
+
>
|
|
186
|
+
|
|
187
|
+
### 2. Azure Tenant ID (se auth detectado)
|
|
188
|
+
**Onde encontrar:** Azure Portal > Azure AD > Properties > Tenant ID
|
|
189
|
+
>
|
|
190
|
+
|
|
191
|
+
### 3. Azure Client Secret (se auth detectado)
|
|
192
|
+
**Onde encontrar:** Azure Portal > App Registrations > {App} > Certificates & secrets
|
|
193
|
+
>
|
|
194
|
+
|
|
195
|
+
### 4. Storage Account Key (se storage detectado)
|
|
196
|
+
**Onde encontrar:** Azure Portal > Storage Account > Access keys
|
|
197
|
+
>
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Validacao de senha:**
|
|
203
|
+
- Minimo 16 caracteres
|
|
204
|
+
- Apenas letras e numeros
|
|
205
|
+
- Se conter @, !, #, $, %, ^, &, * → ALERTAR sobre problemas de escape
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### FASE 3: VALIDACAO DE CUSTOS
|
|
210
|
+
|
|
211
|
+
**Integrar com cost-guardian:**
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Validar custos antes de deploy
|
|
215
|
+
npx morph-spec cost infra/main.bicep --verbose
|
|
216
|
+
|
|
217
|
+
# Se custo > limite configurado:
|
|
218
|
+
# 1. PARAR deployment
|
|
219
|
+
# 2. Mostrar breakdown de custos
|
|
220
|
+
# 3. Requerer ADR em decisions.md
|
|
221
|
+
# 4. Requerer aprovacao explicita
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Limites padrao:**
|
|
225
|
+
| Limite | Valor | Acao |
|
|
226
|
+
|--------|-------|------|
|
|
227
|
+
| Free Tier | $0 | Automatico |
|
|
228
|
+
| Com Aprovacao | $10/mes | Requer confirmacao |
|
|
229
|
+
| Requer ADR | $10+/mes | Requer documentacao |
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### FASE 4: DEPLOY DE INFRAESTRUTURA
|
|
234
|
+
|
|
235
|
+
**4.1 Verificar se Bicep existe:**
|
|
236
|
+
|
|
237
|
+
```powershell
|
|
238
|
+
# Verificar estrutura
|
|
239
|
+
Test-Path "infra/main.bicep"
|
|
240
|
+
Test-Path "infra/parameters.dev.json"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Se NAO existir:
|
|
244
|
+
```markdown
|
|
245
|
+
## Templates Bicep nao encontrados
|
|
246
|
+
|
|
247
|
+
O projeto nao possui arquivos de infraestrutura em `infra/`.
|
|
248
|
+
|
|
249
|
+
Opcoes:
|
|
250
|
+
1. **Criar agora** - Gerar templates baseado no projeto detectado
|
|
251
|
+
2. **Usar /morph-infra** - Rodar comando de setup de infra primeiro
|
|
252
|
+
3. **Cancelar** - Abortar deploy
|
|
253
|
+
|
|
254
|
+
Qual opcao voce prefere?
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**4.2 Criar Resource Group:**
|
|
258
|
+
|
|
259
|
+
```powershell
|
|
260
|
+
# Padrao de nomenclatura: rg-{projeto}-{ambiente}
|
|
261
|
+
az group create --name rg-$PROJECT-$ENV --location brazilsouth
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**4.3 What-If (OBRIGATORIO):**
|
|
265
|
+
|
|
266
|
+
```powershell
|
|
267
|
+
az deployment group what-if `
|
|
268
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
269
|
+
--template-file infra/main.bicep `
|
|
270
|
+
--parameters @infra/parameters.$ENV.json
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**PAUSA OBRIGATORIA:**
|
|
274
|
+
```markdown
|
|
275
|
+
## Recursos a serem criados/modificados
|
|
276
|
+
|
|
277
|
+
[Output do what-if aqui]
|
|
278
|
+
|
|
279
|
+
Deseja prosseguir com o deploy? (sim/nao)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**4.4 Deploy Bicep:**
|
|
283
|
+
|
|
284
|
+
```powershell
|
|
285
|
+
az deployment group create `
|
|
286
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
287
|
+
--template-file infra/main.bicep `
|
|
288
|
+
--parameters @infra/parameters.$ENV.json `
|
|
289
|
+
--name "deploy-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**4.5 Capturar outputs:**
|
|
293
|
+
|
|
294
|
+
```powershell
|
|
295
|
+
# Salvar outputs para proximas fases
|
|
296
|
+
$outputs = az deployment group show `
|
|
297
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
298
|
+
--name $DEPLOYMENT_NAME `
|
|
299
|
+
--query properties.outputs -o json | ConvertFrom-Json
|
|
300
|
+
|
|
301
|
+
# Extrair valores
|
|
302
|
+
$acrName = $outputs.acrName.value
|
|
303
|
+
$appUrl = $outputs.containerAppUrl.value
|
|
304
|
+
$sqlServer = $outputs.sqlServerFqdn.value
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
### FASE 5: DEPLOY DE APLICACAO
|
|
310
|
+
|
|
311
|
+
**5.1 Build Docker:**
|
|
312
|
+
|
|
313
|
+
```powershell
|
|
314
|
+
# IMPORTANTE: Dockerfile deve usar .NET 10
|
|
315
|
+
# Restaurar apenas projeto web, NAO solution (evita projetos de teste)
|
|
316
|
+
|
|
317
|
+
docker build -t $ACR_NAME.azurecr.io/$PROJECT`:$TAG .
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Dockerfile recomendado para .NET 10:**
|
|
321
|
+
```dockerfile
|
|
322
|
+
# Build stage
|
|
323
|
+
FROM mcr.microsoft.com/dotnet/sdk:10.0-preview AS build
|
|
324
|
+
WORKDIR /src
|
|
325
|
+
|
|
326
|
+
# Restaurar APENAS projeto web (nao solution!)
|
|
327
|
+
COPY ["src/$PROJECT.Web.Blazor/$PROJECT.Web.Blazor.csproj", "src/$PROJECT.Web.Blazor/"]
|
|
328
|
+
COPY ["src/$PROJECT.Application/$PROJECT.Application.csproj", "src/$PROJECT.Application/"]
|
|
329
|
+
COPY ["src/$PROJECT.Domain/$PROJECT.Domain.csproj", "src/$PROJECT.Domain/"]
|
|
330
|
+
COPY ["src/$PROJECT.Infrastructure/$PROJECT.Infrastructure.csproj", "src/$PROJECT.Infrastructure/"]
|
|
331
|
+
RUN dotnet restore "src/$PROJECT.Web.Blazor/$PROJECT.Web.Blazor.csproj"
|
|
332
|
+
|
|
333
|
+
COPY . .
|
|
334
|
+
RUN dotnet publish "src/$PROJECT.Web.Blazor/$PROJECT.Web.Blazor.csproj" -c Release -o /app/publish
|
|
335
|
+
|
|
336
|
+
# Runtime stage
|
|
337
|
+
FROM mcr.microsoft.com/dotnet/aspnet:10.0-preview AS runtime
|
|
338
|
+
WORKDIR /app
|
|
339
|
+
COPY --from=build /app/publish .
|
|
340
|
+
|
|
341
|
+
ENV ASPNETCORE_URLS=http://+:8080
|
|
342
|
+
ENV ASPNETCORE_ENVIRONMENT=Production
|
|
343
|
+
EXPOSE 8080
|
|
344
|
+
|
|
345
|
+
ENTRYPOINT ["dotnet", "$PROJECT.Web.Blazor.dll"]
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**5.2 Push para ACR:**
|
|
349
|
+
|
|
350
|
+
```powershell
|
|
351
|
+
# Habilitar admin (necessario para Container App)
|
|
352
|
+
az acr update --name $ACR_NAME --admin-enabled true
|
|
353
|
+
|
|
354
|
+
# Login no ACR
|
|
355
|
+
az acr login --name $ACR_NAME
|
|
356
|
+
|
|
357
|
+
# Push
|
|
358
|
+
docker push $ACR_NAME.azurecr.io/$PROJECT`:$TAG
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**5.3 Criar/Atualizar Container App:**
|
|
362
|
+
|
|
363
|
+
```powershell
|
|
364
|
+
# Obter senha do ACR
|
|
365
|
+
$acrPassword = az acr credential show --name $ACR_NAME --query "passwords[0].value" -o tsv
|
|
366
|
+
|
|
367
|
+
# Criar Container App (se nao existe)
|
|
368
|
+
az containerapp create `
|
|
369
|
+
--name $PROJECT-$ENV-app `
|
|
370
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
371
|
+
--environment $PROJECT-$ENV-app-env `
|
|
372
|
+
--image $ACR_NAME.azurecr.io/$PROJECT`:$TAG `
|
|
373
|
+
--registry-server $ACR_NAME.azurecr.io `
|
|
374
|
+
--registry-username $ACR_NAME `
|
|
375
|
+
--registry-password $acrPassword `
|
|
376
|
+
--target-port 8080 `
|
|
377
|
+
--ingress external `
|
|
378
|
+
--min-replicas 1 `
|
|
379
|
+
--max-replicas 3 `
|
|
380
|
+
--cpu 0.25 `
|
|
381
|
+
--memory 0.5Gi
|
|
382
|
+
|
|
383
|
+
# OU atualizar imagem (se ja existe)
|
|
384
|
+
az containerapp update `
|
|
385
|
+
--name $PROJECT-$ENV-app `
|
|
386
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
387
|
+
--image $ACR_NAME.azurecr.io/$PROJECT`:$TAG
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**5.4 Configurar Environment Variables:**
|
|
391
|
+
|
|
392
|
+
```powershell
|
|
393
|
+
# CRITICO: Usar nomes EXATOS do codigo!
|
|
394
|
+
az containerapp update `
|
|
395
|
+
--name $PROJECT-$ENV-app `
|
|
396
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
397
|
+
--set-env-vars `
|
|
398
|
+
"ConnectionStrings__DefaultConnection=$SQL_CONNECTION_STRING" `
|
|
399
|
+
"Azure__Storage__ConnectionString=$STORAGE_CONNECTION_STRING" `
|
|
400
|
+
"ApplicationInsights__ConnectionString=$APPINSIGHTS_CONNECTION_STRING" `
|
|
401
|
+
"ASPNETCORE_ENVIRONMENT=Production"
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**5.5 Sticky Sessions (OBRIGATORIO para Blazor Server):**
|
|
405
|
+
|
|
406
|
+
```powershell
|
|
407
|
+
# Se Blazor Server detectado, SEMPRE executar:
|
|
408
|
+
az containerapp ingress sticky-sessions set `
|
|
409
|
+
--name $PROJECT-$ENV-app `
|
|
410
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
411
|
+
--affinity sticky
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**5.6 SQL Firewall:**
|
|
415
|
+
|
|
416
|
+
```powershell
|
|
417
|
+
# Permitir Azure Services
|
|
418
|
+
az sql server firewall-rule create `
|
|
419
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
420
|
+
--server $SQL_SERVER_NAME `
|
|
421
|
+
--name AllowAzureServices `
|
|
422
|
+
--start-ip-address 0.0.0.0 `
|
|
423
|
+
--end-ip-address 0.0.0.0
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**5.7 Migrations:**
|
|
427
|
+
|
|
428
|
+
```powershell
|
|
429
|
+
# IMPORTANTE: Usar path completo se dotnet-ef nao estiver no PATH
|
|
430
|
+
~/.dotnet/tools/dotnet-ef database update `
|
|
431
|
+
--project src/$PROJECT.Infrastructure `
|
|
432
|
+
--startup-project src/$PROJECT.Web.Blazor `
|
|
433
|
+
--connection "$SQL_CONNECTION_STRING"
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
### FASE 6: VERIFICACAO E ROLLBACK
|
|
439
|
+
|
|
440
|
+
**6.1 Health Check:**
|
|
441
|
+
|
|
442
|
+
```powershell
|
|
443
|
+
# Verificar status da revisao
|
|
444
|
+
$health = az containerapp revision list `
|
|
445
|
+
--name $PROJECT-$ENV-app `
|
|
446
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
447
|
+
--query "[0].properties.healthState" -o tsv
|
|
448
|
+
|
|
449
|
+
if ($health -ne "Healthy") {
|
|
450
|
+
Write-Error "Container App not healthy! Initiating rollback..."
|
|
451
|
+
# Trigger rollback
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
**6.2 Smoke Tests:**
|
|
456
|
+
|
|
457
|
+
```powershell
|
|
458
|
+
# Obter URL
|
|
459
|
+
$appUrl = az containerapp show `
|
|
460
|
+
--name $PROJECT-$ENV-app `
|
|
461
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
462
|
+
--query properties.configuration.ingress.fqdn -o tsv
|
|
463
|
+
|
|
464
|
+
# Testar HTTPS
|
|
465
|
+
$response = Invoke-WebRequest -Uri "https://$appUrl" -UseBasicParsing
|
|
466
|
+
if ($response.StatusCode -ne 200) {
|
|
467
|
+
Write-Error "App not responding! Status: $($response.StatusCode)"
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
**6.3 Rollback Automatico:**
|
|
472
|
+
|
|
473
|
+
```powershell
|
|
474
|
+
# Listar revisoes
|
|
475
|
+
$revisions = az containerapp revision list `
|
|
476
|
+
--name $PROJECT-$ENV-app `
|
|
477
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
478
|
+
--query "[].name" -o tsv
|
|
479
|
+
|
|
480
|
+
# Ativar revisao anterior
|
|
481
|
+
$previousRevision = $revisions[1] # Segunda revisao (anterior)
|
|
482
|
+
az containerapp revision activate `
|
|
483
|
+
--name $PROJECT-$ENV-app `
|
|
484
|
+
--resource-group rg-$PROJECT-$ENV `
|
|
485
|
+
--revision $previousRevision
|
|
486
|
+
|
|
487
|
+
Write-Output "Rollback executado para revisao: $previousRevision"
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**6.4 Checklist de Verificacao:**
|
|
491
|
+
|
|
492
|
+
```markdown
|
|
493
|
+
## Verificacao Final
|
|
494
|
+
|
|
495
|
+
- [ ] Container App rodando (Healthy)
|
|
496
|
+
- [ ] Health check passando (HTTP 200)
|
|
497
|
+
- [ ] HTTPS acessivel: https://{app-url}
|
|
498
|
+
- [ ] Database conectado (testar query simples)
|
|
499
|
+
- [ ] Blazor circuit estabelecido (se aplicavel)
|
|
500
|
+
- [ ] Logs sem erros criticos
|
|
501
|
+
|
|
502
|
+
Todos os checks passaram? (sim/nao)
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## TROUBLESHOOTING KNOWLEDGE BASE
|
|
508
|
+
|
|
509
|
+
### Erros Comuns de Deploy
|
|
510
|
+
|
|
511
|
+
| Erro | Causa | Solucao |
|
|
512
|
+
|------|-------|---------|
|
|
513
|
+
| `winget not recognized` | Windows sem winget | Baixar MSI: https://aka.ms/installazurecliwindows |
|
|
514
|
+
| `MFA/tenant erro` | Login sem tenant | `az login --tenant <TENANT-ID>` |
|
|
515
|
+
| `KeyVault not found` | Parameters.json referencia KV inexistente | Criar parameters.dev.initial.json com valores diretos |
|
|
516
|
+
| `Container App timeout` | Deploy tudo junto, imagem nao existe | Deploy em 2 fases: infra primeiro, app depois |
|
|
517
|
+
| `Login failed for user` | Senha com caracteres especiais | Usar senha alfanumerica simples |
|
|
518
|
+
| `Escape de caracteres` | Senha tipo `F1sh@rt!` | Mudar para `FishArt2025SecurePwd` |
|
|
519
|
+
| `dotnet-ef not found` | Tool nao esta no PATH | Usar `~/.dotnet/tools/dotnet-ef` |
|
|
520
|
+
| `Projetos teste nao encontrados` | Dockerfile restaura .sln | Restaurar apenas projeto web |
|
|
521
|
+
|
|
522
|
+
### Erros de Container Apps
|
|
523
|
+
|
|
524
|
+
| Erro | Causa | Solucao |
|
|
525
|
+
|------|-------|---------|
|
|
526
|
+
| `ContainerCreating` stuck | Imagem nao existe no ACR | Verificar `docker push` completou |
|
|
527
|
+
| `CrashLoopBackOff` | App crasha no startup | Checar logs: `az containerapp logs show` |
|
|
528
|
+
| `ImagePullBackOff` | Credenciais ACR erradas | `az acr update --admin-enabled true` |
|
|
529
|
+
| `401 Unauthorized` | ACR auth falhou | Verificar registry-server e credentials |
|
|
530
|
+
| `504 Gateway Timeout` | App lento para iniciar | Aumentar `initialDelaySeconds` no probe |
|
|
531
|
+
|
|
532
|
+
### Erros de Blazor Server
|
|
533
|
+
|
|
534
|
+
| Erro | Causa | Solucao |
|
|
535
|
+
|------|-------|---------|
|
|
536
|
+
| `CircuitDisconnected` | Sticky sessions desabilitado | `az containerapp ingress sticky-sessions set --affinity sticky` |
|
|
537
|
+
| `WebSocket failed` | SignalR sem sticky | Mesmo acima |
|
|
538
|
+
| `CSS/JS not loading` | Static files middleware | `app.UseStaticFiles()` antes de `app.UseAntiforgery()` |
|
|
539
|
+
| `Render mode error` | MainLayout com @rendermode | Remover @rendermode do MainLayout |
|
|
540
|
+
| `Pre-rendering hydration` | State nao persistido | Usar `[PersistentState]` attribute |
|
|
541
|
+
|
|
542
|
+
### Erros de SQL
|
|
543
|
+
|
|
544
|
+
| Erro | Causa | Solucao |
|
|
545
|
+
|------|-------|---------|
|
|
546
|
+
| `Login failed` | Connection string com escape | Mudar senha SQL para algo simples |
|
|
547
|
+
| `Firewall blocks` | Azure Services bloqueado | `az sql server firewall-rule create ... 0.0.0.0` |
|
|
548
|
+
| `Connection timeout` | IP nao liberado | Adicionar IP do Container App |
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
## MODO --AUTO PARA CI/CD
|
|
553
|
+
|
|
554
|
+
Para uso em pipelines Azure DevOps:
|
|
555
|
+
|
|
556
|
+
```bash
|
|
557
|
+
# Uso automatico (sem pausas interativas)
|
|
558
|
+
npx morph-spec deploy prod --auto \
|
|
559
|
+
--sql-password "$(SQL_PASSWORD)" \
|
|
560
|
+
--tenant-id "$(TENANT_ID)" \
|
|
561
|
+
--client-secret "$(CLIENT_SECRET)" \
|
|
562
|
+
--storage-key "$(STORAGE_KEY)" \
|
|
563
|
+
--skip-confirmation
|
|
564
|
+
|
|
565
|
+
# Flags disponiveis:
|
|
566
|
+
# --auto Modo automatico (sem pausas)
|
|
567
|
+
# --skip-confirmation Pular what-if confirmation
|
|
568
|
+
# --skip-build Nao fazer docker build (usar imagem existente)
|
|
569
|
+
# --infra-only Apenas deploy de infra (Bicep)
|
|
570
|
+
# --app-only Apenas deploy de app (Container App)
|
|
571
|
+
# --dry-run Validar sem executar
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
## INTEGRACAO AZURE DEVOPS
|
|
577
|
+
|
|
578
|
+
### Pipeline Template
|
|
579
|
+
|
|
580
|
+
```yaml
|
|
581
|
+
# azure-pipelines.yml
|
|
582
|
+
trigger:
|
|
583
|
+
branches:
|
|
584
|
+
include:
|
|
585
|
+
- main
|
|
586
|
+
- develop
|
|
587
|
+
|
|
588
|
+
variables:
|
|
589
|
+
- group: 'deploy-secrets' # Variable group com secrets
|
|
590
|
+
|
|
591
|
+
stages:
|
|
592
|
+
- stage: Build
|
|
593
|
+
jobs:
|
|
594
|
+
- job: BuildAndPush
|
|
595
|
+
pool:
|
|
596
|
+
vmImage: 'ubuntu-latest'
|
|
597
|
+
steps:
|
|
598
|
+
- task: Docker@2
|
|
599
|
+
inputs:
|
|
600
|
+
containerRegistry: 'acr-connection'
|
|
601
|
+
repository: '$(projectName)'
|
|
602
|
+
command: 'buildAndPush'
|
|
603
|
+
Dockerfile: '**/Dockerfile'
|
|
604
|
+
tags: '$(Build.BuildId)'
|
|
605
|
+
|
|
606
|
+
- stage: DeployDev
|
|
607
|
+
dependsOn: Build
|
|
608
|
+
condition: eq(variables['Build.SourceBranch'], 'refs/heads/develop')
|
|
609
|
+
jobs:
|
|
610
|
+
- deployment: DeployToDev
|
|
611
|
+
environment: 'dev'
|
|
612
|
+
strategy:
|
|
613
|
+
runOnce:
|
|
614
|
+
deploy:
|
|
615
|
+
steps:
|
|
616
|
+
- script: |
|
|
617
|
+
npx morph-spec deploy dev --auto \
|
|
618
|
+
--sql-password "$(SqlPassword)" \
|
|
619
|
+
--skip-confirmation
|
|
620
|
+
displayName: 'Deploy to Dev'
|
|
621
|
+
|
|
622
|
+
- stage: DeployProd
|
|
623
|
+
dependsOn: Build
|
|
624
|
+
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
|
|
625
|
+
jobs:
|
|
626
|
+
- deployment: DeployToProd
|
|
627
|
+
environment: 'prod'
|
|
628
|
+
strategy:
|
|
629
|
+
runOnce:
|
|
630
|
+
deploy:
|
|
631
|
+
steps:
|
|
632
|
+
- script: |
|
|
633
|
+
npx morph-spec deploy prod --auto \
|
|
634
|
+
--sql-password "$(SqlPasswordProd)" \
|
|
635
|
+
--skip-confirmation
|
|
636
|
+
displayName: 'Deploy to Prod'
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## COMANDOS UTEIS
|
|
642
|
+
|
|
643
|
+
```powershell
|
|
644
|
+
# Ver status do deployment
|
|
645
|
+
az deployment group show --resource-group $RG --name $DEPLOYMENT --query properties.provisioningState
|
|
646
|
+
|
|
647
|
+
# Listar recursos criados
|
|
648
|
+
az resource list --resource-group $RG --output table
|
|
649
|
+
|
|
650
|
+
# Ver env vars atuais
|
|
651
|
+
az containerapp show --name $APP --resource-group $RG --query "properties.template.containers[0].env"
|
|
652
|
+
|
|
653
|
+
# Ver logs em tempo real
|
|
654
|
+
az containerapp logs show --name $APP --resource-group $RG --follow
|
|
655
|
+
|
|
656
|
+
# Escalar manualmente
|
|
657
|
+
az containerapp update --name $APP --resource-group $RG --min-replicas 2
|
|
658
|
+
|
|
659
|
+
# Atualizar imagem
|
|
660
|
+
az containerapp update --name $APP --resource-group $RG --image $ACR.azurecr.io/$PROJECT:v2
|
|
661
|
+
|
|
662
|
+
# Restart (apos mudar secrets)
|
|
663
|
+
$revision = az containerapp revision list --name $APP --resource-group $RG --query "[0].name" -o tsv
|
|
664
|
+
az containerapp revision restart --name $APP --resource-group $RG --revision $revision
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
## MAPEAMENTO CONFIG → ENV VAR
|
|
670
|
+
|
|
671
|
+
| No Codigo (.NET) | Environment Variable |
|
|
672
|
+
|------------------|---------------------|
|
|
673
|
+
| `ConnectionStrings:DefaultConnection` | `ConnectionStrings__DefaultConnection` |
|
|
674
|
+
| `ConnectionStrings:HangfireConnection` | `ConnectionStrings__HangfireConnection` |
|
|
675
|
+
| `Azure:Storage:ConnectionString` | `Azure__Storage__ConnectionString` |
|
|
676
|
+
| `Azure:Storage:ContainerName` | `Azure__Storage__ContainerName` |
|
|
677
|
+
| `Azure:KeyVault` | `Azure__KeyVault` |
|
|
678
|
+
| `ApplicationInsights:ConnectionString` | `ApplicationInsights__ConnectionString` |
|
|
679
|
+
| `Clerk:SecretKey` | `Clerk__SecretKey` |
|
|
680
|
+
| `Clerk:PublishableKey` | `Clerk__PublishableKey` |
|
|
681
|
+
| `AzureAd:TenantId` | `AzureAd__TenantId` |
|
|
682
|
+
| `AzureAd:ClientId` | `AzureAd__ClientId` |
|
|
683
|
+
| `AzureAd:ClientSecret` | `AzureAd__ClientSecret` |
|
|
684
|
+
|
|
685
|
+
**Regra:** Substitua `:` por `__` (double underscore)
|
|
686
|
+
|
|
687
|
+
---
|
|
688
|
+
|
|
689
|
+
## DOCUMENTACAO
|
|
690
|
+
|
|
691
|
+
- [Container Apps Docs](https://learn.microsoft.com/azure/container-apps/)
|
|
692
|
+
- [Bicep Reference](https://learn.microsoft.com/azure/azure-resource-manager/bicep/)
|
|
693
|
+
- [Blazor Server Hosting](https://learn.microsoft.com/aspnet/core/blazor/host-and-deploy/)
|
|
694
|
+
- [ACR Authentication](https://learn.microsoft.com/azure/container-registry/container-registry-authentication)
|
|
695
|
+
- [Azure CLI Reference](https://learn.microsoft.com/cli/azure/)
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
*Azure Deploy Specialist v1.0 - MORPH-SPEC by Polymorphism Tech*
|