@polymorphism-tech/morph-spec 2.2.0 → 2.4.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 +314 -1673
- package/LICENSE +72 -72
- package/README.md +515 -516
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +358 -173
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/task-manager.js +429 -0
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/bin/validate.js +369 -0
- 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-apply.md +221 -158
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -0
- package/content/.claude/commands/morph-proposal.md +122 -101
- package/content/.claude/commands/morph-status.md +86 -86
- package/content/.claude/commands/morph-troubleshoot.md +122 -0
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/checklists/code-review.md +226 -0
- package/content/.claude/skills/checklists/morph-checklist.md +117 -0
- package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
- package/content/.claude/skills/infra/bicep-architect.md +126 -419
- package/content/.claude/skills/infra/container-specialist.md +131 -437
- package/content/.claude/skills/infra/devops-engineer.md +119 -405
- package/content/.claude/skills/integrations/asaas-financial.md +130 -333
- package/content/.claude/skills/integrations/azure-identity.md +142 -309
- package/content/.claude/skills/integrations/clerk-auth.md +108 -290
- package/content/.claude/skills/integrations/resend-email.md +119 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
- package/content/.claude/skills/specialists/azure-architect.md +142 -142
- package/content/.claude/skills/specialists/code-analyzer.md +235 -0
- package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
- package/content/.claude/skills/specialists/ef-modeler.md +113 -200
- package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -245
- package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
- package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
- package/content/.claude/skills/specialists/standards-architect.md +156 -78
- package/content/.claude/skills/specialists/testing-specialist.md +126 -0
- package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1060
- package/content/.claude/skills/stacks/dotnet-blazor.md +210 -588
- package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
- package/content/.claude/skills/workflows/morph-replicate.md +213 -0
- package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
- package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
- package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
- package/content/.claude/skills/workflows/phase-tasks.md +164 -0
- package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +378 -242
- package/content/.morph/config/config.template.json +89 -108
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/design-impl.md +37 -0
- package/content/.morph/docs/workflows/fast-track.md +29 -0
- package/content/.morph/docs/workflows/full-morph.md +76 -0
- package/content/.morph/docs/workflows/standard.md +44 -0
- package/content/.morph/docs/workflows/ui-refresh.md +39 -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 -0
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
- package/content/.morph/examples/scheduled-reports/spec.md +267 -0
- package/content/.morph/examples/state-v3.json +188 -0
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +190 -239
- package/content/.morph/hooks/pre-commit-agents.sh +24 -24
- 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/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -0
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
- package/content/.morph/standards/agent-framework-production.md +410 -0
- package/content/.morph/standards/agent-framework-setup.md +413 -453
- package/content/.morph/standards/agent-framework-workflows.md +349 -0
- package/content/.morph/standards/architecture.md +325 -325
- package/content/.morph/standards/azure.md +605 -379
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/dotnet10-migration.md +520 -494
- 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/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/agent.cs +163 -172
- package/content/.morph/templates/clarify-questions.md +159 -0
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -0
- package/content/.morph/templates/contracts/Entities.cs +25 -0
- package/content/.morph/templates/contracts/Queries.cs +74 -0
- package/content/.morph/templates/contracts/README.md +74 -0
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/decisions.md +123 -106
- 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/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 -0
- 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/proposal.md +141 -155
- package/content/.morph/templates/recap.md +94 -105
- 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/simulation.md +353 -0
- package/content/.morph/templates/spec.md +149 -148
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/state.template.json +222 -222
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/tasks.md +257 -235
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-components.md +362 -276
- 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/CLAUDE.md +150 -442
- 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/detectors/structure-detector.js +245 -250
- package/docs/README.md +144 -149
- 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/getting-started.md +301 -302
- package/docs/installation.md +361 -361
- package/docs/templates.md +418 -418
- package/docs/validation-checklist.md +265 -266
- package/package.json +80 -80
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +183 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -0
- package/src/commands/create-story.js +351 -351
- package/src/commands/detect-agents.js +139 -0
- package/src/commands/detect.js +104 -104
- package/src/commands/doctor.js +356 -280
- package/src/commands/generate.js +149 -149
- package/src/commands/init.js +258 -245
- package/src/commands/lint-fluent.js +352 -0
- package/src/commands/rollback-phase.js +185 -0
- package/src/commands/session-summary.js +291 -0
- 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/task.js +78 -0
- package/src/commands/troubleshoot.js +222 -0
- package/src/commands/update.js +192 -159
- package/src/commands/validate-blazor-state.js +210 -0
- package/src/commands/validate-blazor.js +156 -0
- package/src/commands/validate-css.js +84 -0
- package/src/commands/validate-phase.js +221 -0
- package/src/lib/blazor-concurrency-analyzer.js +288 -0
- package/src/lib/blazor-state-validator.js +291 -0
- package/src/lib/blazor-validator.js +374 -0
- package/src/lib/complexity-analyzer.js +441 -292
- package/src/lib/continuous-validator.js +421 -0
- package/src/lib/css-validator.js +352 -0
- package/src/lib/decision-constraint-loader.js +109 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/learning-system.js +520 -0
- package/src/lib/mockup-generator.js +366 -0
- package/src/lib/recap-generator.js +205 -0
- package/src/lib/state-manager.js +397 -340
- package/src/lib/troubleshoot-grep.js +194 -0
- package/src/lib/troubleshoot-index.js +144 -0
- package/src/lib/ui-detector.js +350 -0
- package/src/lib/validation-runner.js +231 -0
- package/src/lib/validators/architecture-validator.js +387 -0
- package/src/lib/validators/contract-compliance-validator.js +273 -0
- package/src/lib/validators/package-validator.js +360 -0
- package/src/lib/validators/ui-contrast-validator.js +422 -0
- package/src/utils/file-copier.js +179 -139
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- package/content/.claude/commands/morph-costs.md +0 -206
- package/content/.claude/commands/morph-tasks.md +0 -319
- package/content/.claude/skills/specialists/cost-guardian.md +0 -110
- package/content/.claude/skills/stacks/shopify.md +0 -445
- package/content/.morph/config/azure-pricing.json +0 -70
- package/content/.morph/config/azure-pricing.schema.json +0 -50
- package/content/.morph/hooks/pre-commit-costs.sh +0 -91
- package/docs/api/cost-calculator.js.html +0 -513
- package/docs/api/design-system-generator.js.html +0 -382
- package/docs/api/global.html +0 -5263
- package/docs/api/index.html +0 -96
- package/docs/api/state-manager.js.html +0 -423
- package/src/commands/cost.js +0 -181
- package/src/commands/update-pricing.js +0 -206
- package/src/lib/cost-calculator.js +0 -429
|
@@ -1,229 +1,229 @@
|
|
|
1
|
-
# ==============================================================================
|
|
2
|
-
# MORPH-SPEC - Deploy Script (PowerShell)
|
|
3
|
-
# Automated deployment of Azure infrastructure
|
|
4
|
-
# ==============================================================================
|
|
5
|
-
|
|
6
|
-
[CmdletBinding()]
|
|
7
|
-
param(
|
|
8
|
-
[Parameter(Mandatory=$false)]
|
|
9
|
-
[string]$AppName = "myapp",
|
|
10
|
-
|
|
11
|
-
[Parameter(Mandatory=$false)]
|
|
12
|
-
[ValidateSet("dev", "staging", "prod")]
|
|
13
|
-
[string]$Environment = "dev",
|
|
14
|
-
|
|
15
|
-
[Parameter(Mandatory=$false)]
|
|
16
|
-
[string]$Location = "eastus",
|
|
17
|
-
|
|
18
|
-
[Parameter(Mandatory=$false)]
|
|
19
|
-
[string]$SubscriptionId,
|
|
20
|
-
|
|
21
|
-
[Parameter(Mandatory=$false)]
|
|
22
|
-
[ValidateSet("appservice", "containerapp")]
|
|
23
|
-
[string]$HostingType = "appservice",
|
|
24
|
-
|
|
25
|
-
[Parameter(Mandatory=$false)]
|
|
26
|
-
[ValidateSet("F1", "B1", "S1", "P1v2")]
|
|
27
|
-
[string]$AppServiceSku = "F1",
|
|
28
|
-
|
|
29
|
-
[Parameter(Mandatory=$false)]
|
|
30
|
-
[string]$ContainerImage = "mcr.microsoft.com/hello-world:latest"
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
# ==============================================================================
|
|
34
|
-
# CONFIGURATION
|
|
35
|
-
# ==============================================================================
|
|
36
|
-
|
|
37
|
-
$ErrorActionPreference = "Stop"
|
|
38
|
-
|
|
39
|
-
$ResourceGroup = "rg-$AppName-$Environment"
|
|
40
|
-
$DeploymentName = "deploy-$AppName-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
|
41
|
-
|
|
42
|
-
# ==============================================================================
|
|
43
|
-
# FUNCTIONS
|
|
44
|
-
# ==============================================================================
|
|
45
|
-
|
|
46
|
-
function Write-InfoLog {
|
|
47
|
-
param([string]$Message)
|
|
48
|
-
Write-Host "ℹ️ $Message" -ForegroundColor Blue
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function Write-SuccessLog {
|
|
52
|
-
param([string]$Message)
|
|
53
|
-
Write-Host "✅ $Message" -ForegroundColor Green
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function Write-WarningLog {
|
|
57
|
-
param([string]$Message)
|
|
58
|
-
Write-Host "⚠️ $Message" -ForegroundColor Yellow
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function Write-ErrorLog {
|
|
62
|
-
param([string]$Message)
|
|
63
|
-
Write-Host "❌ $Message" -ForegroundColor Red
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function Test-Prerequisites {
|
|
67
|
-
Write-InfoLog "Checking prerequisites..."
|
|
68
|
-
|
|
69
|
-
# Check Azure CLI
|
|
70
|
-
$azCliInstalled = Get-Command az -ErrorAction SilentlyContinue
|
|
71
|
-
if (-not $azCliInstalled) {
|
|
72
|
-
Write-ErrorLog "Azure CLI not found. Install from: https://aka.ms/azure-cli"
|
|
73
|
-
exit 1
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
# Check login
|
|
77
|
-
try {
|
|
78
|
-
$null = az account show 2>$null
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
Write-ErrorLog "Not logged in to Azure. Run: az login"
|
|
82
|
-
exit 1
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
# Set subscription if provided
|
|
86
|
-
if ($SubscriptionId) {
|
|
87
|
-
Write-InfoLog "Setting subscription to: $SubscriptionId"
|
|
88
|
-
az account set --subscription $SubscriptionId
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
Write-SuccessLog "Prerequisites checked"
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function New-ResourceGroupIfNotExists {
|
|
95
|
-
Write-InfoLog "Creating resource group: $ResourceGroup"
|
|
96
|
-
|
|
97
|
-
$exists = az group exists -n $ResourceGroup
|
|
98
|
-
if ($exists -eq "true") {
|
|
99
|
-
Write-WarningLog "Resource group already exists"
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
az group create `
|
|
103
|
-
--name $ResourceGroup `
|
|
104
|
-
--location $Location `
|
|
105
|
-
--tags `
|
|
106
|
-
environment=$Environment `
|
|
107
|
-
application=$AppName `
|
|
108
|
-
managedBy=bicep `
|
|
109
|
-
framework=morph-spec
|
|
110
|
-
|
|
111
|
-
Write-SuccessLog "Resource group created"
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function New-SqlPassword {
|
|
116
|
-
# Generate secure random password
|
|
117
|
-
$bytes = New-Object byte[] 32
|
|
118
|
-
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($bytes)
|
|
119
|
-
$password = [Convert]::ToBase64String($bytes) -replace '[=+/]', '' | Select-Object -First 25
|
|
120
|
-
|
|
121
|
-
Write-SuccessLog "SQL password generated (stored in Key Vault after deploy)"
|
|
122
|
-
return $password
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function Deploy-Infrastructure {
|
|
126
|
-
param([string]$SqlPassword)
|
|
127
|
-
|
|
128
|
-
Write-InfoLog "Deploying infrastructure..."
|
|
129
|
-
Write-InfoLog " App Name: $AppName"
|
|
130
|
-
Write-InfoLog " Environment: $Environment"
|
|
131
|
-
Write-InfoLog " Hosting Type: $HostingType"
|
|
132
|
-
Write-InfoLog " Location: $Location"
|
|
133
|
-
|
|
134
|
-
# Prepare parameters file
|
|
135
|
-
$paramsFile = "parameters.$Environment.json"
|
|
136
|
-
|
|
137
|
-
if (-not (Test-Path $paramsFile)) {
|
|
138
|
-
Write-ErrorLog "Parameters file not found: $paramsFile"
|
|
139
|
-
exit 1
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
# Deploy
|
|
143
|
-
az deployment group create `
|
|
144
|
-
--resource-group $ResourceGroup `
|
|
145
|
-
--name $DeploymentName `
|
|
146
|
-
--template-file main.bicep `
|
|
147
|
-
--parameters "@$paramsFile" `
|
|
148
|
-
--parameters `
|
|
149
|
-
appName=$AppName `
|
|
150
|
-
environment=$Environment `
|
|
151
|
-
location=$Location `
|
|
152
|
-
hostingType=$HostingType `
|
|
153
|
-
appServiceSku=$AppServiceSku `
|
|
154
|
-
containerImage=$ContainerImage `
|
|
155
|
-
sqlAdminPassword=$SqlPassword `
|
|
156
|
-
--output table
|
|
157
|
-
|
|
158
|
-
Write-SuccessLog "Infrastructure deployed"
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function Show-Outputs {
|
|
162
|
-
Write-InfoLog "Retrieving deployment outputs..."
|
|
163
|
-
|
|
164
|
-
$appUrl = az deployment group show `
|
|
165
|
-
-g $ResourceGroup `
|
|
166
|
-
-n $DeploymentName `
|
|
167
|
-
--query properties.outputs.appUrl.value -o tsv
|
|
168
|
-
|
|
169
|
-
$sqlConnection = az deployment group show `
|
|
170
|
-
-g $ResourceGroup `
|
|
171
|
-
-n $DeploymentName `
|
|
172
|
-
--query properties.outputs.sqlConnectionString.value -o tsv
|
|
173
|
-
|
|
174
|
-
$appInsightsConnection = az deployment group show `
|
|
175
|
-
-g $ResourceGroup `
|
|
176
|
-
-n $DeploymentName `
|
|
177
|
-
--query properties.outputs.appInsightsConnectionString.value -o tsv
|
|
178
|
-
|
|
179
|
-
Write-Host ""
|
|
180
|
-
Write-Host "╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Green
|
|
181
|
-
Write-Host "║ DEPLOYMENT SUCCESSFUL ║" -ForegroundColor Green
|
|
182
|
-
Write-Host "╚════════════════════════════════════════════════════════════════╝" -ForegroundColor Green
|
|
183
|
-
Write-Host ""
|
|
184
|
-
Write-Host "🌐 Application URL:" -ForegroundColor Cyan
|
|
185
|
-
Write-Host " $appUrl"
|
|
186
|
-
Write-Host ""
|
|
187
|
-
Write-Host "🗄️ SQL Connection String:" -ForegroundColor Cyan
|
|
188
|
-
Write-Host " $sqlConnection"
|
|
189
|
-
Write-Host ""
|
|
190
|
-
Write-Host "📊 App Insights Connection String:" -ForegroundColor Cyan
|
|
191
|
-
Write-Host " $appInsightsConnection"
|
|
192
|
-
Write-Host ""
|
|
193
|
-
Write-Host "💡 Next steps:" -ForegroundColor Yellow
|
|
194
|
-
|
|
195
|
-
if ($HostingType -eq "appservice") {
|
|
196
|
-
Write-Host " 1. Deploy your code: az webapp up --name app-$AppName-$Environment"
|
|
197
|
-
Write-Host " 2. View logs: az webapp log tail --name app-$AppName-$Environment -g $ResourceGroup"
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
Write-Host " 1. Build and push container: az acr build --registry <ACR> --image ${AppName}:latest ."
|
|
201
|
-
Write-Host " 2. Update container app: az containerapp update -n ca-$AppName-$Environment -g $ResourceGroup --image <IMAGE>"
|
|
202
|
-
Write-Host " 3. View logs: az containerapp logs show -n ca-$AppName-$Environment -g $ResourceGroup --follow"
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
Write-Host ""
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
# ==============================================================================
|
|
209
|
-
# MAIN
|
|
210
|
-
# ==============================================================================
|
|
211
|
-
|
|
212
|
-
function Main {
|
|
213
|
-
Write-Host ""
|
|
214
|
-
Write-Host "╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
|
|
215
|
-
Write-Host "║ MORPH-SPEC - Azure Infrastructure Deploy ║" -ForegroundColor Cyan
|
|
216
|
-
Write-Host "╚════════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
|
|
217
|
-
Write-Host ""
|
|
218
|
-
|
|
219
|
-
Test-Prerequisites
|
|
220
|
-
New-ResourceGroupIfNotExists
|
|
221
|
-
$sqlPassword = New-SqlPassword
|
|
222
|
-
Deploy-Infrastructure -SqlPassword $sqlPassword
|
|
223
|
-
Show-Outputs
|
|
224
|
-
|
|
225
|
-
Write-SuccessLog "Deployment complete! 🚀"
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
# Run main function
|
|
229
|
-
Main
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# MORPH-SPEC - Deploy Script (PowerShell)
|
|
3
|
+
# Automated deployment of Azure infrastructure
|
|
4
|
+
# ==============================================================================
|
|
5
|
+
|
|
6
|
+
[CmdletBinding()]
|
|
7
|
+
param(
|
|
8
|
+
[Parameter(Mandatory=$false)]
|
|
9
|
+
[string]$AppName = "myapp",
|
|
10
|
+
|
|
11
|
+
[Parameter(Mandatory=$false)]
|
|
12
|
+
[ValidateSet("dev", "staging", "prod")]
|
|
13
|
+
[string]$Environment = "dev",
|
|
14
|
+
|
|
15
|
+
[Parameter(Mandatory=$false)]
|
|
16
|
+
[string]$Location = "eastus",
|
|
17
|
+
|
|
18
|
+
[Parameter(Mandatory=$false)]
|
|
19
|
+
[string]$SubscriptionId,
|
|
20
|
+
|
|
21
|
+
[Parameter(Mandatory=$false)]
|
|
22
|
+
[ValidateSet("appservice", "containerapp")]
|
|
23
|
+
[string]$HostingType = "appservice",
|
|
24
|
+
|
|
25
|
+
[Parameter(Mandatory=$false)]
|
|
26
|
+
[ValidateSet("F1", "B1", "S1", "P1v2")]
|
|
27
|
+
[string]$AppServiceSku = "F1",
|
|
28
|
+
|
|
29
|
+
[Parameter(Mandatory=$false)]
|
|
30
|
+
[string]$ContainerImage = "mcr.microsoft.com/hello-world:latest"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# ==============================================================================
|
|
34
|
+
# CONFIGURATION
|
|
35
|
+
# ==============================================================================
|
|
36
|
+
|
|
37
|
+
$ErrorActionPreference = "Stop"
|
|
38
|
+
|
|
39
|
+
$ResourceGroup = "rg-$AppName-$Environment"
|
|
40
|
+
$DeploymentName = "deploy-$AppName-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
|
41
|
+
|
|
42
|
+
# ==============================================================================
|
|
43
|
+
# FUNCTIONS
|
|
44
|
+
# ==============================================================================
|
|
45
|
+
|
|
46
|
+
function Write-InfoLog {
|
|
47
|
+
param([string]$Message)
|
|
48
|
+
Write-Host "ℹ️ $Message" -ForegroundColor Blue
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function Write-SuccessLog {
|
|
52
|
+
param([string]$Message)
|
|
53
|
+
Write-Host "✅ $Message" -ForegroundColor Green
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function Write-WarningLog {
|
|
57
|
+
param([string]$Message)
|
|
58
|
+
Write-Host "⚠️ $Message" -ForegroundColor Yellow
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function Write-ErrorLog {
|
|
62
|
+
param([string]$Message)
|
|
63
|
+
Write-Host "❌ $Message" -ForegroundColor Red
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function Test-Prerequisites {
|
|
67
|
+
Write-InfoLog "Checking prerequisites..."
|
|
68
|
+
|
|
69
|
+
# Check Azure CLI
|
|
70
|
+
$azCliInstalled = Get-Command az -ErrorAction SilentlyContinue
|
|
71
|
+
if (-not $azCliInstalled) {
|
|
72
|
+
Write-ErrorLog "Azure CLI not found. Install from: https://aka.ms/azure-cli"
|
|
73
|
+
exit 1
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Check login
|
|
77
|
+
try {
|
|
78
|
+
$null = az account show 2>$null
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
Write-ErrorLog "Not logged in to Azure. Run: az login"
|
|
82
|
+
exit 1
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Set subscription if provided
|
|
86
|
+
if ($SubscriptionId) {
|
|
87
|
+
Write-InfoLog "Setting subscription to: $SubscriptionId"
|
|
88
|
+
az account set --subscription $SubscriptionId
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Write-SuccessLog "Prerequisites checked"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function New-ResourceGroupIfNotExists {
|
|
95
|
+
Write-InfoLog "Creating resource group: $ResourceGroup"
|
|
96
|
+
|
|
97
|
+
$exists = az group exists -n $ResourceGroup
|
|
98
|
+
if ($exists -eq "true") {
|
|
99
|
+
Write-WarningLog "Resource group already exists"
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
az group create `
|
|
103
|
+
--name $ResourceGroup `
|
|
104
|
+
--location $Location `
|
|
105
|
+
--tags `
|
|
106
|
+
environment=$Environment `
|
|
107
|
+
application=$AppName `
|
|
108
|
+
managedBy=bicep `
|
|
109
|
+
framework=morph-spec
|
|
110
|
+
|
|
111
|
+
Write-SuccessLog "Resource group created"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function New-SqlPassword {
|
|
116
|
+
# Generate secure random password
|
|
117
|
+
$bytes = New-Object byte[] 32
|
|
118
|
+
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($bytes)
|
|
119
|
+
$password = [Convert]::ToBase64String($bytes) -replace '[=+/]', '' | Select-Object -First 25
|
|
120
|
+
|
|
121
|
+
Write-SuccessLog "SQL password generated (stored in Key Vault after deploy)"
|
|
122
|
+
return $password
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function Deploy-Infrastructure {
|
|
126
|
+
param([string]$SqlPassword)
|
|
127
|
+
|
|
128
|
+
Write-InfoLog "Deploying infrastructure..."
|
|
129
|
+
Write-InfoLog " App Name: $AppName"
|
|
130
|
+
Write-InfoLog " Environment: $Environment"
|
|
131
|
+
Write-InfoLog " Hosting Type: $HostingType"
|
|
132
|
+
Write-InfoLog " Location: $Location"
|
|
133
|
+
|
|
134
|
+
# Prepare parameters file
|
|
135
|
+
$paramsFile = "parameters.$Environment.json"
|
|
136
|
+
|
|
137
|
+
if (-not (Test-Path $paramsFile)) {
|
|
138
|
+
Write-ErrorLog "Parameters file not found: $paramsFile"
|
|
139
|
+
exit 1
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# Deploy
|
|
143
|
+
az deployment group create `
|
|
144
|
+
--resource-group $ResourceGroup `
|
|
145
|
+
--name $DeploymentName `
|
|
146
|
+
--template-file main.bicep `
|
|
147
|
+
--parameters "@$paramsFile" `
|
|
148
|
+
--parameters `
|
|
149
|
+
appName=$AppName `
|
|
150
|
+
environment=$Environment `
|
|
151
|
+
location=$Location `
|
|
152
|
+
hostingType=$HostingType `
|
|
153
|
+
appServiceSku=$AppServiceSku `
|
|
154
|
+
containerImage=$ContainerImage `
|
|
155
|
+
sqlAdminPassword=$SqlPassword `
|
|
156
|
+
--output table
|
|
157
|
+
|
|
158
|
+
Write-SuccessLog "Infrastructure deployed"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function Show-Outputs {
|
|
162
|
+
Write-InfoLog "Retrieving deployment outputs..."
|
|
163
|
+
|
|
164
|
+
$appUrl = az deployment group show `
|
|
165
|
+
-g $ResourceGroup `
|
|
166
|
+
-n $DeploymentName `
|
|
167
|
+
--query properties.outputs.appUrl.value -o tsv
|
|
168
|
+
|
|
169
|
+
$sqlConnection = az deployment group show `
|
|
170
|
+
-g $ResourceGroup `
|
|
171
|
+
-n $DeploymentName `
|
|
172
|
+
--query properties.outputs.sqlConnectionString.value -o tsv
|
|
173
|
+
|
|
174
|
+
$appInsightsConnection = az deployment group show `
|
|
175
|
+
-g $ResourceGroup `
|
|
176
|
+
-n $DeploymentName `
|
|
177
|
+
--query properties.outputs.appInsightsConnectionString.value -o tsv
|
|
178
|
+
|
|
179
|
+
Write-Host ""
|
|
180
|
+
Write-Host "╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Green
|
|
181
|
+
Write-Host "║ DEPLOYMENT SUCCESSFUL ║" -ForegroundColor Green
|
|
182
|
+
Write-Host "╚════════════════════════════════════════════════════════════════╝" -ForegroundColor Green
|
|
183
|
+
Write-Host ""
|
|
184
|
+
Write-Host "🌐 Application URL:" -ForegroundColor Cyan
|
|
185
|
+
Write-Host " $appUrl"
|
|
186
|
+
Write-Host ""
|
|
187
|
+
Write-Host "🗄️ SQL Connection String:" -ForegroundColor Cyan
|
|
188
|
+
Write-Host " $sqlConnection"
|
|
189
|
+
Write-Host ""
|
|
190
|
+
Write-Host "📊 App Insights Connection String:" -ForegroundColor Cyan
|
|
191
|
+
Write-Host " $appInsightsConnection"
|
|
192
|
+
Write-Host ""
|
|
193
|
+
Write-Host "💡 Next steps:" -ForegroundColor Yellow
|
|
194
|
+
|
|
195
|
+
if ($HostingType -eq "appservice") {
|
|
196
|
+
Write-Host " 1. Deploy your code: az webapp up --name app-$AppName-$Environment"
|
|
197
|
+
Write-Host " 2. View logs: az webapp log tail --name app-$AppName-$Environment -g $ResourceGroup"
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
Write-Host " 1. Build and push container: az acr build --registry <ACR> --image ${AppName}:latest ."
|
|
201
|
+
Write-Host " 2. Update container app: az containerapp update -n ca-$AppName-$Environment -g $ResourceGroup --image <IMAGE>"
|
|
202
|
+
Write-Host " 3. View logs: az containerapp logs show -n ca-$AppName-$Environment -g $ResourceGroup --follow"
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
Write-Host ""
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# ==============================================================================
|
|
209
|
+
# MAIN
|
|
210
|
+
# ==============================================================================
|
|
211
|
+
|
|
212
|
+
function Main {
|
|
213
|
+
Write-Host ""
|
|
214
|
+
Write-Host "╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
|
|
215
|
+
Write-Host "║ MORPH-SPEC - Azure Infrastructure Deploy ║" -ForegroundColor Cyan
|
|
216
|
+
Write-Host "╚════════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
|
|
217
|
+
Write-Host ""
|
|
218
|
+
|
|
219
|
+
Test-Prerequisites
|
|
220
|
+
New-ResourceGroupIfNotExists
|
|
221
|
+
$sqlPassword = New-SqlPassword
|
|
222
|
+
Deploy-Infrastructure -SqlPassword $sqlPassword
|
|
223
|
+
Show-Outputs
|
|
224
|
+
|
|
225
|
+
Write-SuccessLog "Deployment complete! 🚀"
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Run main function
|
|
229
|
+
Main
|