@polymorphism-tech/morph-spec 4.6.0 → 4.7.1

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.
Files changed (239) hide show
  1. package/README.md +414 -700
  2. package/docs/ARCHITECTURE.md +331 -0
  3. package/docs/CHEATSHEET.md +221 -0
  4. package/docs/COMMAND-FLOWS.md +368 -0
  5. package/docs/QUICKSTART.md +212 -0
  6. package/docs/examples/order-management/contracts.cs +84 -0
  7. package/docs/examples/order-management/proposal.md +24 -0
  8. package/docs/examples/order-management/spec.md +162 -0
  9. package/docs/plans/2026-02-23-ddd-architecture-refactor.md +1153 -0
  10. package/docs/plans/2026-02-23-ddd-nextsteps.md +682 -0
  11. package/docs/plans/2026-02-23-infra-architect-refactor.md +437 -0
  12. package/docs/plans/2026-02-23-nextjs-code-review-design.md +156 -0
  13. package/docs/plans/2026-02-23-nextjs-code-review-impl.md +1254 -0
  14. package/docs/plans/2026-02-23-nextjs-standards-design.md +149 -0
  15. package/docs/plans/2026-02-23-nextjs-standards-impl.md +1846 -0
  16. package/framework/agents/README.md +14 -14
  17. package/framework/agents/architecture/standards-architect.md +159 -159
  18. package/framework/agents/frontend/nextjs-expert.md +87 -127
  19. package/framework/agents/infrastructure/azure-architect.md +147 -147
  20. package/framework/agents/infrastructure/infra-architect.md +45 -0
  21. package/framework/agents.json +1145 -278
  22. package/framework/rules/frontend-standards.md +0 -3
  23. package/framework/rules/nextjs-standards.md +17 -0
  24. package/framework/skills/level-0-meta/code-review-nextjs/SKILL.md +147 -0
  25. package/framework/skills/level-0-meta/code-review-nextjs/references/review-example-nextjs.md +254 -0
  26. package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +3 -3
  27. package/framework/skills/level-1-workflows/phase-design/SKILL.md +45 -9
  28. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +38 -0
  29. package/framework/standards/STANDARDS.json +121 -0
  30. package/framework/standards/architecture/ddd/bounded-contexts.md +105 -0
  31. package/framework/standards/architecture/ddd/complexity-levels.md +108 -0
  32. package/framework/standards/architecture/ddd/ubiquitous-language.md +58 -0
  33. package/framework/standards/frontend/nextjs/app-router.md +123 -0
  34. package/framework/standards/frontend/nextjs/components.md +132 -0
  35. package/framework/standards/frontend/nextjs/data-fetching.md +126 -0
  36. package/framework/standards/frontend/nextjs/forms.md +128 -0
  37. package/framework/standards/frontend/nextjs/naming-conventions.md +67 -0
  38. package/framework/standards/frontend/nextjs/project-structure.md +102 -0
  39. package/framework/standards/frontend/nextjs/state-management.md +72 -0
  40. package/framework/standards/frontend/nextjs/testing.md +111 -0
  41. package/framework/templates/REGISTRY.json +538 -142
  42. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +69 -0
  43. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +86 -0
  44. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +41 -0
  45. package/framework/templates/docs/spec.md +49 -0
  46. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -0
  47. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -0
  48. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -0
  49. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -0
  50. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -0
  51. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -0
  52. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -0
  53. package/framework/templates/project-structure/dotnet-ddd.md +70 -0
  54. package/framework/workflows/docs/enforcement-pipeline.md +2 -1
  55. package/package.json +1 -1
  56. package/scripts/scan-nextjs.mjs +169 -0
  57. package/src/commands/project/doctor.js +52 -1
  58. package/src/commands/project/init.js +15 -1
  59. package/src/commands/project/update.js +6 -1
  60. package/src/lib/standards/standards-context-injector.js +5 -0
  61. package/src/lib/validators/nextjs/index.js +6 -0
  62. package/src/lib/validators/nextjs/next-component-validator.js +181 -0
  63. package/src/lib/validators/validation-runner.js +5 -0
  64. package/src/utils/agents-installer.js +14 -2
  65. package/.morph/.morphversion +0 -5
  66. package/.morph/analytics/threads-log.jsonl +0 -6
  67. package/.morph/config/config.json +0 -8
  68. package/.morph/framework/agents.json +0 -948
  69. package/.morph/framework/standards/STANDARDS.json +0 -812
  70. package/.morph/framework/standards/ai-agents/blazor-ui.md +0 -364
  71. package/.morph/framework/standards/ai-agents/production.md +0 -415
  72. package/.morph/framework/standards/ai-agents/setup.md +0 -418
  73. package/.morph/framework/standards/ai-agents/team-orchestration.md +0 -479
  74. package/.morph/framework/standards/ai-agents/workflows.md +0 -354
  75. package/.morph/framework/standards/architecture/ddd/aggregates.md +0 -120
  76. package/.morph/framework/standards/architecture/ddd/entities.md +0 -99
  77. package/.morph/framework/standards/architecture/ddd/value-objects.md +0 -124
  78. package/.morph/framework/standards/backend/api/minimal-api.md +0 -494
  79. package/.morph/framework/standards/backend/api/rest.md +0 -492
  80. package/.morph/framework/standards/backend/api/validation.md +0 -88
  81. package/.morph/framework/standards/backend/authentication/passkeys.md +0 -428
  82. package/.morph/framework/standards/backend/database/ef-core.md +0 -199
  83. package/.morph/framework/standards/backend/database/migrations.md +0 -393
  84. package/.morph/framework/standards/backend/database/postgresql/database.md +0 -352
  85. package/.morph/framework/standards/backend/database/repository-patterns.md +0 -528
  86. package/.morph/framework/standards/backend/database/vector-search-rag.md +0 -541
  87. package/.morph/framework/standards/backend/dotnet/async.md +0 -366
  88. package/.morph/framework/standards/backend/dotnet/core.md +0 -117
  89. package/.morph/framework/standards/backend/dotnet/di.md +0 -439
  90. package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  91. package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +0 -216
  92. package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
  93. package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
  94. package/.morph/framework/standards/backend/integrations/resend/resend-email.md +0 -385
  95. package/.morph/framework/standards/context/analytics.md +0 -96
  96. package/.morph/framework/standards/context/bundles.md +0 -110
  97. package/.morph/framework/standards/context/priming.md +0 -78
  98. package/.morph/framework/standards/core/architecture.md +0 -185
  99. package/.morph/framework/standards/core/coding.md +0 -214
  100. package/.morph/framework/standards/core/git-branching-strategy.md +0 -403
  101. package/.morph/framework/standards/core/git.md +0 -185
  102. package/.morph/framework/standards/core/testing.md +0 -295
  103. package/.morph/framework/standards/data/nosql/blob-storage.md +0 -102
  104. package/.morph/framework/standards/data/nosql/cache/redis.md +0 -97
  105. package/.morph/framework/standards/data/nosql/cosmos-db.md +0 -118
  106. package/.morph/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  107. package/.morph/framework/standards/data/vector-search/rag-chunking.md +0 -104
  108. package/.morph/framework/standards/frontend/blazor/design-checklist.md +0 -222
  109. package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  110. package/.morph/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  111. package/.morph/framework/standards/frontend/blazor/html-conversion.md +0 -184
  112. package/.morph/framework/standards/frontend/blazor/lifecycle.md +0 -195
  113. package/.morph/framework/standards/frontend/blazor/pitfalls.md +0 -198
  114. package/.morph/framework/standards/frontend/blazor/state.md +0 -191
  115. package/.morph/framework/standards/frontend/design-system/animations.md +0 -151
  116. package/.morph/framework/standards/frontend/design-system/naming.md +0 -64
  117. package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +0 -215
  118. package/.morph/framework/standards/infrastructure/azure/azure.md +0 -624
  119. package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  120. package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  121. package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  122. package/.morph/framework/standards/infrastructure/azure/services/functions.md +0 -486
  123. package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  124. package/.morph/framework/standards/infrastructure/azure/services/storage.md +0 -407
  125. package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +0 -196
  126. package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +0 -252
  127. package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
  128. package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
  129. package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
  130. package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
  131. package/.morph/framework/standards/integration/api/graphql.md +0 -91
  132. package/.morph/framework/standards/integration/api/grpc.md +0 -114
  133. package/.morph/framework/standards/integration/api/rest-design.md +0 -95
  134. package/.morph/framework/standards/integration/event-driven/cqrs.md +0 -101
  135. package/.morph/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  136. package/.morph/framework/standards/integration/event-driven/service-bus.md +0 -95
  137. package/.morph/framework/standards/integration/mcp/mcp-tools.md +0 -384
  138. package/.morph/framework/standards/observability/logging.md +0 -131
  139. package/.morph/framework/standards/observability/metrics.md +0 -121
  140. package/.morph/framework/standards/observability/monitoring.md +0 -114
  141. package/.morph/framework/standards/observability/tracing.md +0 -132
  142. package/.morph/framework/standards/workflows/parallel-execution.md +0 -112
  143. package/.morph/framework/standards/workflows/thread-management.md +0 -113
  144. package/.morph/framework/templates/.idea/morph-templates.xml +0 -92
  145. package/.morph/framework/templates/.vscode/morph-templates.code-snippets +0 -186
  146. package/.morph/framework/templates/IDE-SNIPPETS.md +0 -266
  147. package/.morph/framework/templates/README.md +0 -814
  148. package/.morph/framework/templates/REGISTRY.json +0 -1492
  149. package/.morph/framework/templates/code/dotnet/backend/repository.cs +0 -141
  150. package/.morph/framework/templates/code/dotnet/backend/service.cs +0 -139
  151. package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  152. package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  153. package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  154. package/.morph/framework/templates/code/dotnet/contracts/README.md +0 -74
  155. package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  156. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
  157. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
  158. package/.morph/framework/templates/code/dotnet/database/migration.cs +0 -83
  159. package/.morph/framework/templates/code/dotnet/frontend/component.razor +0 -239
  160. package/.morph/framework/templates/code/dotnet/jobs/agent.cs +0 -163
  161. package/.morph/framework/templates/code/dotnet/jobs/job.cs +0 -171
  162. package/.morph/framework/templates/code/dotnet/test.cs +0 -239
  163. package/.morph/framework/templates/code/sql/rls-policy.sql +0 -57
  164. package/.morph/framework/templates/code/sql/supabase-migration.sql +0 -100
  165. package/.morph/framework/templates/code/sql/supabase-migration.template.sql +0 -113
  166. package/.morph/framework/templates/code/typescript/contracts.ts +0 -168
  167. package/.morph/framework/templates/context/CONTEXT-FEATURE.md +0 -276
  168. package/.morph/framework/templates/context/CONTEXT.md +0 -181
  169. package/.morph/framework/templates/docs/clarifications.md +0 -253
  170. package/.morph/framework/templates/docs/onboarding.md +0 -123
  171. package/.morph/framework/templates/docs/proposal.md +0 -182
  172. package/.morph/framework/templates/docs/schema-analysis.md +0 -119
  173. package/.morph/framework/templates/docs/spec.md +0 -149
  174. package/.morph/framework/templates/docs/ui-components.md +0 -124
  175. package/.morph/framework/templates/docs/ui-design-system.md +0 -76
  176. package/.morph/framework/templates/docs/ui-flows.md +0 -167
  177. package/.morph/framework/templates/docs/ui-mockups.md +0 -98
  178. package/.morph/framework/templates/docs/user-stories.md +0 -34
  179. package/.morph/framework/templates/examples/design-system-examples.md +0 -357
  180. package/.morph/framework/templates/examples/spec-examples.md +0 -90
  181. package/.morph/framework/templates/feature/decisions.md +0 -187
  182. package/.morph/framework/templates/feature/recap.md +0 -146
  183. package/.morph/framework/templates/feature/tasks.md +0 -199
  184. package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  185. package/.morph/framework/templates/infrastructure/azure/README.md +0 -286
  186. package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  187. package/.morph/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  188. package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  189. package/.morph/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  190. package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  191. package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  192. package/.morph/framework/templates/infrastructure/azure/deploy.sh +0 -208
  193. package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  194. package/.morph/framework/templates/infrastructure/azure/main.bicep +0 -189
  195. package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  196. package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  197. package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  198. package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  199. package/.morph/framework/templates/infrastructure/azure/storage.bicep +0 -106
  200. package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +0 -58
  201. package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +0 -67
  202. package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +0 -38
  203. package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +0 -48
  204. package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +0 -54
  205. package/.morph/framework/templates/infrastructure/github/README.md +0 -593
  206. package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  207. package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -45
  208. package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +0 -27
  209. package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  210. package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
  211. package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -59
  212. package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -39
  213. package/.morph/framework/templates/integrations/asaas-client.cs +0 -387
  214. package/.morph/framework/templates/integrations/asaas-webhook.cs +0 -351
  215. package/.morph/framework/templates/integrations/azure-identity-config.cs +0 -288
  216. package/.morph/framework/templates/integrations/clerk-config.cs +0 -258
  217. package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +0 -76
  218. package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +0 -100
  219. package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
  220. package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
  221. package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
  222. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
  223. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
  224. package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +0 -90
  225. package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +0 -126
  226. package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +0 -43
  227. package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +0 -107
  228. package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +0 -95
  229. package/.morph/framework/templates/saas/subscription.cs +0 -347
  230. package/.morph/framework/templates/saas/tenant.cs +0 -338
  231. package/.morph/framework/templates/state.template.json +0 -17
  232. package/.morph/framework/templates/ui/FluentDesignTheme.cs +0 -149
  233. package/.morph/framework/templates/ui/MudTheme.cs +0 -281
  234. package/.morph/framework/templates/ui/design-system.css +0 -226
  235. package/.morph/logs/tool-failures.log +0 -7
  236. package/.morph/memory/pre-compact-2026-02-23T15-43-03-521Z.json +0 -16
  237. package/.morph/state.json +0 -48
  238. package/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
  239. package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
@@ -1,593 +0,0 @@
1
- # GitHub Actions Templates for MORPH-SPEC
2
-
3
- > **Framework-Level CI/CD Templates for Azure App Service & EasyPanel Deployments**
4
-
5
- ## Overview
6
-
7
- This directory contains reusable GitHub Actions workflows and composite actions that enable CI/CD automation for both **blazor-azure** (Azure App Service) and **nextjs-supabase** (EasyPanel/Docker) stacks.
8
-
9
- **Key Features:**
10
- - ✅ Framework-level reusability across stacks
11
- - ✅ Handlebars v2.0 templating with helpers
12
- - ✅ OIDC authentication for Azure (no long-lived secrets)
13
- - ✅ Composite actions for shared logic
14
- - ✅ Stack-specific override mechanism
15
-
16
- ---
17
-
18
- ## 📁 Structure
19
-
20
- ```
21
- infrastructure/github/
22
- ├── workflows/ # Reusable workflow templates
23
- │ ├── dotnet-build.yml.hbs # .NET restore, build, test, coverage
24
- │ ├── docker-build-push.yml.hbs # Docker build & push to registry
25
- │ ├── deploy-azure-app-service.yml.hbs # Azure App Service deployment
26
- │ └── deploy-easypanel.yml.hbs # EasyPanel deployment via webhook
27
-
28
- └── actions/ # Composite action templates
29
- ├── docker-build-push/action.yml.hbs # Build & push Docker image
30
- ├── health-check/action.yml.hbs # Poll health endpoint
31
- └── azure-auth/action.yml.hbs # Azure OIDC login
32
- ```
33
-
34
- ---
35
-
36
- ## 🔄 Reusable Workflows vs Composite Actions
37
-
38
- | Type | Purpose | When to Use | Example |
39
- |------|---------|-------------|---------|
40
- | **Reusable Workflows** | Complete CI/CD pipeline (multiple jobs) | Build + test + deploy | `dotnet-build.yml.hbs`, `deploy-azure-app-service.yml.hbs` |
41
- | **Composite Actions** | Single responsibility (grouped steps) | Reusable task across workflows | `azure-auth/action.yml.hbs`, `health-check/action.yml.hbs` |
42
-
43
- ### Reusable Workflows
44
-
45
- **Characteristics:**
46
- - Defined with `on: workflow_call`
47
- - Can have multiple jobs
48
- - Accept inputs and secrets via `with:` and `secrets: inherit`
49
- - Called from other workflows using `uses:` at job level
50
-
51
- **Example Usage:**
52
- ```yaml
53
- jobs:
54
- build:
55
- uses: ./.github/workflows/dotnet-build.yml
56
- with:
57
- dotnet-version: '10.0'
58
- run-tests: true
59
- secrets: inherit
60
- ```
61
-
62
- ### Composite Actions
63
-
64
- **Characteristics:**
65
- - Defined with `runs: using: 'composite'`
66
- - Bundle related shell commands
67
- - Lightweight (no containerization needed)
68
- - Called using `uses:` at step level
69
-
70
- **Example Usage:**
71
- ```yaml
72
- steps:
73
- - name: Azure Login
74
- uses: ./.github/actions/azure-auth
75
- with:
76
- client-id: ${{ secrets.AZURE_CLIENT_ID }}
77
- tenant-id: ${{ secrets.AZURE_TENANT_ID }}
78
- subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
79
- ```
80
-
81
- ---
82
-
83
- ## 🏗️ Deployment Architectures
84
-
85
- ### Blazor-Azure (Azure App Service)
86
-
87
- **Deployment Flow:**
88
- 1. **Build:** `dotnet restore` → `dotnet build` → `dotnet test`
89
- 2. **Publish:** `dotnet publish -c Release -o ./publish`
90
- 3. **Infrastructure:** Deploy Bicep (App Service Plan + App Service)
91
- 4. **Deploy:** `azure/webapps-deploy@v2` with publish folder
92
- 5. **Health Check:** Poll `/health` endpoint
93
-
94
- **Key Characteristics:**
95
- - ✅ Direct .NET publish (no Docker)
96
- - ✅ OIDC authentication (Federated Identity)
97
- - ✅ Bicep IaC for infrastructure
98
- - ✅ App Service deployment slots for blue-green
99
-
100
- **GitHub Secrets Required:**
101
- - `AZURE_CLIENT_ID` - Entra ID app registration client ID
102
- - `AZURE_TENANT_ID` - Azure AD tenant ID
103
- - `AZURE_SUBSCRIPTION_ID` - Azure subscription ID
104
-
105
- **Workflows:**
106
- - Framework: `deploy-azure-app-service.yml.hbs`
107
- - Stack: `stacks/blazor-azure/.morph/framework/templates/infrastructure/github/workflows/cd-prod.yml.hbs`
108
-
109
- ### NextJS-Supabase (EasyPanel/Docker)
110
-
111
- **Deployment Flow:**
112
- 1. **Build Backend:** `dotnet restore` → `dotnet build` → `dotnet test`
113
- 2. **Build Frontend:** `npm ci` → `npm run build` → `npm test`
114
- 3. **Docker:** Multi-stage build for API + Web
115
- 4. **Push:** Docker image to GitHub Container Registry (ghcr.io)
116
- 5. **Deploy:** Trigger EasyPanel webhook with image tag
117
- 6. **Health Check:** Poll `/health` endpoint
118
-
119
- **Key Characteristics:**
120
- - ✅ Docker-based deployment
121
- - ✅ Multi-service (API + Web)
122
- - ✅ GitHub Container Registry (ghcr.io)
123
- - ✅ EasyPanel webhook deployment
124
-
125
- **GitHub Secrets Required:**
126
- - `GITHUB_TOKEN` - Auto-provided for ghcr.io
127
- - `EASYPANEL_WEBHOOK_URL` - EasyPanel deployment webhook
128
- - `EASYPANEL_API_TOKEN` - EasyPanel API authentication
129
- - `APP_URL` - Application URL for health checks
130
-
131
- **Workflows:**
132
- - Framework: `docker-build-push.yml.hbs`, `deploy-easypanel.yml.hbs`
133
- - Stack: `stacks/nextjs-supabase/.morph/framework/templates/infrastructure/github/workflows/cd-prod.yml.hbs`
134
-
135
- ---
136
-
137
- ## 🔐 Authentication & Security
138
-
139
- ### Azure OIDC (Blazor-Azure)
140
-
141
- **Setup Steps:**
142
-
143
- 1. **Create Entra ID App Registration:**
144
- ```bash
145
- az ad app create --display-name "GitHub-Blazor-Azure-OIDC"
146
- ```
147
-
148
- 2. **Configure Federated Credentials:**
149
- ```bash
150
- az ad app federated-credential create \
151
- --id <APP_ID> \
152
- --parameters '{
153
- "name": "github-prod",
154
- "issuer": "https://token.actions.githubusercontent.com",
155
- "subject": "repo:<ORG>/<REPO>:environment:production",
156
- "audiences": ["api://AzureADTokenExchange"]
157
- }'
158
- ```
159
-
160
- 3. **Assign RBAC Roles:**
161
- ```bash
162
- az role assignment create \
163
- --assignee <APP_ID> \
164
- --role "Contributor" \
165
- --scope /subscriptions/<SUBSCRIPTION_ID>
166
- ```
167
-
168
- 4. **Configure GitHub Secrets:**
169
- - `AZURE_CLIENT_ID` - App registration client ID
170
- - `AZURE_TENANT_ID` - Tenant ID
171
- - `AZURE_SUBSCRIPTION_ID` - Subscription ID
172
-
173
- **Workflow Usage:**
174
- ```yaml
175
- - name: Azure Login (OIDC)
176
- uses: azure/login@v1
177
- with:
178
- client-id: ${{ secrets.AZURE_CLIENT_ID }}
179
- tenant-id: ${{ secrets.AZURE_TENANT_ID }}
180
- subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
181
- ```
182
-
183
- ### GitHub Container Registry (NextJS-Supabase)
184
-
185
- **Setup:**
186
-
187
- 1. **Enable GHCR:**
188
- - No additional setup needed - `GITHUB_TOKEN` is auto-provided
189
-
190
- 2. **Workflow Usage:**
191
- ```yaml
192
- - name: Login to GHCR
193
- uses: docker/login-action@v3
194
- with:
195
- registry: ghcr.io
196
- username: ${{ github.actor }}
197
- password: ${{ secrets.GITHUB_TOKEN }}
198
- ```
199
-
200
- 3. **Image Naming:**
201
- ```yaml
202
- image: ghcr.io/${{ github.repository_owner }}/myapp:${{ github.sha }}
203
- ```
204
-
205
- ---
206
-
207
- ## 📝 Handlebars Variables & Helpers
208
-
209
- ### Auto-Injected Variables
210
-
211
- | Variable | Example | Source |
212
- |----------|---------|--------|
213
- | `{{APP_NAME}}` | `myapp` | config.json → project.name |
214
- | `{{DOTNET_VERSION}}` | `10.0` | config.json → dotnet.version |
215
- | `{{GITHUB_OWNER}}` | `myorg` | config.json → repository.owner |
216
- | `{{DATE}}` | `2026-02-18` | Generated at render time |
217
- | `{{YEAR}}` | `2026` | Generated at render time |
218
-
219
- ### Handlebars Helpers
220
-
221
- | Helper | Input | Output | Use Case |
222
- |--------|-------|--------|----------|
223
- | `{{kebabCase str}}` | `MyApp` | `my-app` | Docker image names, Azure resources |
224
- | `{{pascalCase str}}` | `my-app` | `MyApp` | Class names (rarely needed in YAML) |
225
- | `{{camelCase str}}` | `my-app` | `myApp` | Variables (rarely needed in YAML) |
226
-
227
- ### Escaping GitHub Actions Syntax
228
-
229
- **Problem:** GitHub Actions uses `${{ }}` syntax, which conflicts with Handlebars.
230
-
231
- **Solution:** Use `{{{{raw}}}}` blocks to preserve GitHub Actions syntax:
232
-
233
- ```yaml
234
- # WRONG (Handlebars will interpret this)
235
- dotnet-version: ${{ inputs.dotnet-version }}
236
-
237
- # CORRECT (Escaped for GitHub Actions)
238
- dotnet-version: {{{{raw}}}}${{ inputs.dotnet-version }}{{{{/raw}}}}
239
- ```
240
-
241
- **In Templates:**
242
- ```handlebars
243
- {{#if run-tests}}
244
- - name: Test
245
- run: dotnet test --configuration {{{{raw}}}}${{ inputs.build-configuration }}{{{{/raw}}}}
246
- {{/if}}
247
- ```
248
-
249
- ---
250
-
251
- ## 🚀 Template Rendering Process
252
-
253
- ### GitHub Actions Constraint
254
-
255
- ❌ **GitHub Actions CANNOT reference parent directories**
256
- - Example: `uses: ../../../../framework/templates/...` ❌ NOT SUPPORTED
257
-
258
- ✅ **Solution:** Render framework templates into each stack's `.github/` directory
259
-
260
- **Rendering Flow:**
261
- ```
262
- framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs
263
- ↓ (render with Handlebars)
264
- stacks/blazor-azure/.github/workflows/dotnet-build.yml
265
- ↓ (commit to repo)
266
- GitHub Actions execution
267
- ```
268
-
269
- ### Rendering Command (Manual for Now)
270
-
271
- **Current Approach:**
272
- ```bash
273
- # Manual rendering using Node.js script (future: CLI command)
274
- node scripts/render-github-workflows.js \
275
- --stack blazor-azure \
276
- --app-name myapp \
277
- --dotnet-version 10.0 \
278
- --output stacks/blazor-azure/.github/
279
- ```
280
-
281
- **Future CLI Command:**
282
- ```bash
283
- # Planned (not yet implemented)
284
- morph-spec template render github-workflows \
285
- --stack blazor-azure \
286
- --environment prod \
287
- --output stacks/blazor-azure/.github/
288
- ```
289
-
290
- ### What Gets Committed
291
-
292
- ✅ **Commit:** Rendered `.yml` files in `.github/workflows/` and `.github/actions/`
293
- ❌ **Don't Commit:** Template sources (`.yml.hbs` files) - these stay in `.morph/framework/templates/`
294
-
295
- **Example:**
296
- ```
297
- # Committed to repo:
298
- .github/
299
- ├── workflows/
300
- │ ├── ci-build.yml # Rendered from template
301
- │ ├── cd-staging.yml # Rendered from template
302
- │ └── cd-prod.yml # Rendered from template
303
- └── actions/
304
- └── azure-auth/
305
- └── action.yml # Rendered from template
306
-
307
- # NOT committed (template sources):
308
- .morph/framework/templates/infrastructure/github/
309
- ├── workflows/
310
- │ ├── ci-build.yml.hbs # Template source
311
- │ └── ...
312
- ```
313
-
314
- ---
315
-
316
- ## 🔀 Stack Override Mechanism
317
-
318
- Templates follow the 3-tier resolution hierarchy:
319
-
320
- 1. **Project-local** (highest priority)
321
- - `.morph/framework/templates/infrastructure/github/workflows/ci-build.yml.hbs`
322
- - Use for project-specific customizations
323
-
324
- 2. **Stack default** (medium priority)
325
- - `stacks/blazor-azure/.morph/framework/templates/infrastructure/github/workflows/ci-build.yml.hbs`
326
- - Stack-specific workflows (production, staging, CI)
327
-
328
- 3. **Framework fallback** (lowest priority)
329
- - `framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs`
330
- - Reusable fragments called by stack workflows
331
-
332
- **Example:**
333
-
334
- Stack workflow `cd-prod.yml.hbs` **calls** framework workflow `dotnet-build.yml.hbs`:
335
- ```yaml
336
- # Stack: stacks/blazor-azure/.morph/framework/templates/.../cd-prod.yml.hbs
337
- jobs:
338
- build:
339
- uses: ./.github/workflows/dotnet-build.yml # Framework template (rendered)
340
- with:
341
- dotnet-version: '{{DOTNET_VERSION}}'
342
- ```
343
-
344
- ---
345
-
346
- ## 🧪 Testing & Validation
347
-
348
- ### Local Testing with `act`
349
-
350
- Use [act](https://github.com/nektos/act) to test GitHub Actions locally:
351
-
352
- ```bash
353
- # Install act
354
- brew install act # macOS
355
- # or: choco install act # Windows
356
-
357
- # List all workflows
358
- cd stacks/blazor-azure
359
- act -l
360
-
361
- # Dry run (validate syntax)
362
- act --dry-run
363
-
364
- # Run specific workflow
365
- act push -W .github/workflows/ci-build.yml
366
-
367
- # Run with secrets (from .secrets file)
368
- act push --secret-file .secrets
369
- ```
370
-
371
- ### Syntax Validation
372
-
373
- **Validate YAML syntax:**
374
- ```bash
375
- # Using yamllint
376
- yamllint .github/workflows/*.yml
377
-
378
- # Using actionlint (GitHub Actions-specific)
379
- actionlint .github/workflows/*.yml
380
- ```
381
-
382
- ### Integration Testing
383
-
384
- **Test in Staging First:**
385
- 1. Push to `staging` branch
386
- 2. Monitor workflow execution in GitHub Actions tab
387
- 3. Verify deployment to staging environment
388
- 4. Test health endpoints
389
- 5. Once validated, merge to `main` for production
390
-
391
- ---
392
-
393
- ## 📊 Workflow Examples
394
-
395
- ### Example 1: CI Build (Blazor-Azure)
396
-
397
- **Stack Template:** `stacks/blazor-azure/.morph/framework/templates/infrastructure/github/workflows/ci-build.yml.hbs`
398
-
399
- ```yaml
400
- name: CI Build
401
-
402
- on:
403
- pull_request:
404
- branches: [main, staging]
405
- push:
406
- branches: [main, staging]
407
-
408
- jobs:
409
- build:
410
- uses: ./.github/workflows/dotnet-build.yml
411
- with:
412
- dotnet-version: '{{DOTNET_VERSION}}'
413
- build-configuration: 'Release'
414
- run-tests: true
415
-
416
- security:
417
- runs-on: ubuntu-latest
418
- steps:
419
- - uses: actions/checkout@v4
420
-
421
- - name: Check vulnerable packages
422
- run: dotnet list package --vulnerable --include-transitive
423
- ```
424
-
425
- ### Example 2: Production Deployment (NextJS-Supabase)
426
-
427
- **Stack Template:** `stacks/nextjs-supabase/.morph/framework/templates/infrastructure/github/workflows/cd-prod.yml.hbs`
428
-
429
- ```yaml
430
- name: Deploy to Production
431
-
432
- on:
433
- push:
434
- branches: [main]
435
-
436
- jobs:
437
- build-docker:
438
- uses: ./.github/workflows/docker-build-push.yml
439
- with:
440
- registry: 'ghcr.io'
441
- image-name: '{{GITHUB_OWNER}}/{{kebabCase APP_NAME}}'
442
- dockerfile-path: 'Dockerfile'
443
- secrets: inherit
444
-
445
- deploy:
446
- needs: build-docker
447
- uses: ./.github/workflows/deploy-easypanel.yml
448
- with:
449
- environment: 'production'
450
- image: {{{{raw}}}}${{ needs.build-docker.outputs.image-tag }}{{{{/raw}}}}
451
- secrets: inherit
452
- ```
453
-
454
- ---
455
-
456
- ## 🔧 Customization Guide
457
-
458
- ### Creating Stack-Specific Workflows
459
-
460
- 1. **Create override template:**
461
- ```bash
462
- mkdir -p stacks/blazor-azure/.morph/framework/templates/infrastructure/github/workflows
463
- ```
464
-
465
- 2. **Copy framework template:**
466
- ```bash
467
- cp framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs \
468
- stacks/blazor-azure/.morph/framework/templates/infrastructure/github/workflows/
469
- ```
470
-
471
- 3. **Customize:**
472
- - Add stack-specific jobs (e.g., blue-green deployment)
473
- - Modify environment variables
474
- - Add security scanning steps
475
-
476
- 4. **Render:**
477
- ```bash
478
- # Manual rendering (future: CLI command)
479
- node scripts/render-github-workflows.js --stack blazor-azure
480
- ```
481
-
482
- ### Adding Custom Composite Actions
483
-
484
- 1. **Create action directory:**
485
- ```bash
486
- mkdir -p framework/templates/infrastructure/github/actions/my-action
487
- ```
488
-
489
- 2. **Create `action.yml.hbs`:**
490
- ```yaml
491
- name: 'My Custom Action'
492
- description: 'Description here'
493
- inputs:
494
- my-input:
495
- description: 'Input description'
496
- required: true
497
-
498
- runs:
499
- using: 'composite'
500
- steps:
501
- - name: Do something
502
- shell: bash
503
- run: |
504
- echo "Input: {{{{raw}}}}${{ inputs.my-input }}{{{{/raw}}}}"
505
- ```
506
-
507
- 3. **Register in REGISTRY.json:**
508
- ```json
509
- {
510
- "id": "github-action-my-action",
511
- "name": "My Custom Action",
512
- "path": "infrastructure/github/actions/my-action/action.yml.hbs",
513
- "location": "framework",
514
- "category": "infrastructure",
515
- "technology": "github-actions",
516
- "engine": "handlebars"
517
- }
518
- ```
519
-
520
- ---
521
-
522
- ## 📚 Resources
523
-
524
- - [GitHub Actions Documentation](https://docs.github.com/en/actions)
525
- - [Reusable Workflows](https://docs.github.com/en/actions/using-workflows/reusing-workflows)
526
- - [Composite Actions](https://docs.github.com/en/actions/creating-actions/creating-a-composite-action)
527
- - [Azure Login Action](https://github.com/Azure/login)
528
- - [Docker Login Action](https://github.com/docker/login-action)
529
- - [OIDC in Azure](https://docs.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation)
530
-
531
- ---
532
-
533
- ## 🐛 Troubleshooting
534
-
535
- ### Common Issues
536
-
537
- **Issue 1: "uses: path is not valid"**
538
- ```yaml
539
- # WRONG
540
- uses: ../../../../framework/templates/.../workflow.yml
541
-
542
- # CORRECT
543
- uses: ./.github/workflows/workflow.yml # Rendered template
544
- ```
545
-
546
- **Issue 2: Handlebars placeholders in rendered YAML**
547
- ```yaml
548
- # Check for unreplaced placeholders
549
- grep -r "{{" .github/workflows/
550
-
551
- # If found, ensure rendering process completed successfully
552
- ```
553
-
554
- **Issue 3: OIDC authentication fails**
555
- ```
556
- Error: Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable
557
- ```
558
-
559
- **Fix:** Ensure federated credentials are configured correctly in Azure AD:
560
- ```bash
561
- # Verify federated credential
562
- az ad app federated-credential show \
563
- --id <APP_ID> \
564
- --federated-credential-id github-prod
565
- ```
566
-
567
- **Issue 4: Health check fails**
568
- ```
569
- curl: (7) Failed to connect to app-myapp-prod.azurewebsites.net
570
- ```
571
-
572
- **Fix:** Add startup delay before health check:
573
- ```yaml
574
- - name: Wait for app startup
575
- run: sleep 30
576
-
577
- - name: Health Check
578
- run: curl --retry 10 --retry-delay 5 ...
579
- ```
580
-
581
- ---
582
-
583
- ## 🎯 Summary
584
-
585
- - ✅ **Framework-level reusability** across blazor-azure and nextjs-supabase stacks
586
- - ✅ **Handlebars v2.0 templating** with helpers (kebabCase, pascalCase, etc.)
587
- - ✅ **OIDC authentication** for Azure (modern, secure, no long-lived secrets)
588
- - ✅ **Composite actions** for shared logic (docker-build-push, health-check, azure-auth)
589
- - ✅ **Reusable workflows** for complete pipelines (dotnet-build, deploy-azure-app-service)
590
- - ✅ **Stack override mechanism** for customization (3-tier resolution)
591
- - ✅ **Rendered outputs committed** to `.github/` (GitHub Actions constraint)
592
-
593
- For questions or issues, see [framework/templates/README.md](../README.md) or open a GitHub issue.
@@ -1,22 +0,0 @@
1
- name: 'Azure Authentication'
2
- description: 'Login to Azure using OIDC'
3
- inputs:
4
- client-id:
5
- description: 'Azure Client ID'
6
- required: true
7
- tenant-id:
8
- description: 'Azure Tenant ID'
9
- required: true
10
- subscription-id:
11
- description: 'Azure Subscription ID'
12
- required: true
13
-
14
- runs:
15
- using: 'composite'
16
- steps:
17
- - name: Azure Login (OIDC)
18
- uses: azure/login@v1
19
- with:
20
- client-id: ${{{{ inputs.client-id }}}}
21
- tenant-id: ${{{{ inputs.tenant-id }}}}
22
- subscription-id: ${{{{ inputs.subscription-id }}}}
@@ -1,45 +0,0 @@
1
- name: 'Build & Push Docker Image'
2
- description: 'Build multi-stage Docker image and push to registry'
3
- inputs:
4
- registry:
5
- description: 'Docker registry URL'
6
- required: true
7
- image-name:
8
- description: 'Docker image name'
9
- required: true
10
- dockerfile-path:
11
- description: 'Path to Dockerfile'
12
- required: false
13
- default: 'Dockerfile'
14
- build-context:
15
- description: 'Docker build context'
16
- required: false
17
- default: '.'
18
- outputs:
19
- image-tag:
20
- description: 'Full image tag with registry'
21
- value: ${{{{ steps.build.outputs.tags }}}}
22
-
23
- runs:
24
- using: 'composite'
25
- steps:
26
- - name: Set up Docker Buildx
27
- uses: docker/setup-buildx-action@v3
28
-
29
- - name: Login to Registry
30
- uses: docker/login-action@v3
31
- with:
32
- registry: ${{{{ inputs.registry }}}}
33
- username: ${{{{ secrets.REGISTRY_USERNAME }}}}
34
- password: ${{{{ secrets.REGISTRY_PASSWORD }}}}
35
-
36
- - name: Build and push
37
- id: build
38
- uses: docker/build-push-action@v5
39
- with:
40
- context: ${{{{ inputs.build-context }}}}
41
- file: ${{{{ inputs.dockerfile-path }}}}
42
- push: true
43
- tags: ${{{{ inputs.registry }}}}/${{{{ inputs.image-name }}}}:${{{{ github.sha }}}}
44
- cache-from: type=gha
45
- cache-to: type=gha,mode=max
@@ -1,27 +0,0 @@
1
- name: 'Health Check'
2
- description: 'Poll health endpoint until ready'
3
- inputs:
4
- url:
5
- description: 'Health check URL'
6
- required: true
7
- timeout:
8
- description: 'Timeout in seconds'
9
- required: false
10
- default: '300'
11
- interval:
12
- description: 'Polling interval in seconds'
13
- required: false
14
- default: '5'
15
-
16
- runs:
17
- using: 'composite'
18
- steps:
19
- - name: Wait for health
20
- shell: bash
21
- run: |
22
- RETRIES=$(($${{{{ inputs.timeout }}}} / ${{{{ inputs.interval }}}}))
23
- curl --retry $RETRIES \
24
- --retry-delay ${{{{ inputs.interval }}}} \
25
- --retry-connrefused \
26
- --fail \
27
- ${{{{ inputs.url }}}}