Add Azure provider pipeline to codegen
Opened by stack72 · 4/7/2026· GitHub #25
Context
We have codegen pipelines for AWS, GCP, Hetzner Cloud, and DigitalOcean that generate swamp extension models from provider API schemas. Azure is the remaining major cloud provider.
Azure is the most complex provider due to:
- Schema source is a Git repo of OpenAPI 2.0 (Swagger) specs (~4,000+ files)
- Specs use allOf extensively for inheritance, requiring a complex normalizer
- Discriminator-based polymorphism needs expansion into concrete property sets
- Long-Running Operations (LRO) with two polling patterns (Azure-AsyncOperation and Location headers)
- Per-resource API versioning (each resource type has its own API version)
- OAuth2 client credentials auth (unlike AWS SDK chain or GCP gcloud)
What Needs to Be Built
Codegen files (codegen/azure/)
pipeline.ts— schema fetching (git clone/update of azure-rest-api-specs), spec discovery with version deduplication, OpenAPI parsing, generation orchestrationextensionModelGenerator.ts— generates per-resource TypeScript model fileslibGenerator.ts— generates_lib/azure.ts(OAuth2 auth, URL template substitution, ARM REST CRUD, LRO polling)normalizer.ts— AzureNormalizer (allOf/oneOf/anyOf flattening, discriminator expansion, type inference, format normalization). This is the hardest part.pathParser.ts—parseEndpointPath()for ARM resource pathsoverrides.ts— schema-specific fixes (case sensitivity, validation relaxation)
Generated output (model/azure/{service}/)
Per-service packages following the same pattern as model/aws/{service}/ and model/gcp/{service}/. Each service directory contains manifest.yaml, deno.json, deno.lock, README.md, LICENSE.txt, and extensions/models/*.ts + _lib/azure.ts.
Wiring
- Add
case "azure"tocodegen/commands/generate.tsandcodegen/commands/fetchSchema.ts - Add
--provider azuretocodegen/main.ts - Add tasks to
codegen/deno.json:fetch-schema:azure,generate:azure,update-lockfiles:azure,bump-versions:azure - Add
generateAzureReadme()tocodegen/shared/readmeGenerator.ts - Add
generateAzureDenoConfig()tocodegen/shared/denoConfigGenerator.ts(justzod— no SDK deps in generated output) - Add
@apidevtools/swagger-parsertocodegen/deno.jsonimports (for OpenAPI dereferencing)
CI
- Add
azure-checkbatch job to.github/workflows/ci.yml(same pattern asaws-checkandgcp-check) - Add
azure-lockfilejob - Add to review
needs:lists
Design Document
Read codegen/designs/azure.md — it covers the full architecture: schema source, normalization, property classification, _lib helper design, model structure, naming conventions, overrides, and implementation order.
Old Code Reference
The original Azure implementation (for the old SI architecture, not swamp) lives at:
/Users/stack72/code/systeminit/si/bin/clover/src/pipelines/azure/
Key files:
spec.ts(1074 lines) —AzureNormalizer,parseEndpointPath(),parseAzureSpec(). This is the core complexity. The normalization logic (allOf flattening, discriminator expansion, intersect/union) ports directly.schema.ts—initAzureRestApiSpecsRepo(),findLatestAzureOpenApiSpecFiles(),readAzureSwaggerSpec(),EXCLUDE_SPECSlist,IGNORE_RESOURCE_TYPESlistoverrides.ts— case sensitivity fixes, validation relaxationpipeline-steps/addDefaultProps.ts— injected properties (resourceGroupName,subscriptionId,resourceIdtemplate,apiVersion,PropUsageMap)funcs/actions/create.ts— LRO polling implementation (Azure-AsyncOperation and Location header patterns)
Important: The old code generates SI-specific output (base classes, action functions). The schema parsing and normalization logic ports directly; the output generation is completely different (swamp extension models with Zod schemas).
Existing Patterns to Follow
Look at these for the established patterns:
codegen/aws/pipeline.ts— per-service generation with CalVer versioning, file writing, deno fmtcodegen/gcp/pipeline.ts— similar but with Discovery Documents instead of CloudFormationcodegen/shared/zodGenerator.ts— converts CfProperty → Zod schema code (reuse for Azure)codegen/shared/schema/types.ts— CfProperty type definitions (Azure normalizer output should produce these)codegen/commands/generate.ts—generateAwsProvider()shows the file-writing loop pattern
Acceptance Criteria
-
deno task fetch-schema:azureclones/updates the azure-rest-api-specs repo -
deno task generate:azureproduces per-service extension packages undermodel/azure/ - Generated models have correct Zod schemas (GlobalArgs from PUT, Resource from GET)
-
_lib/azure.tshandles OAuth2 auth, URL template substitution, ARM CRUD, and LRO polling - Generation is idempotent (second run produces 0 changes)
-
deno check,deno lint,deno fmt --checkall pass on generated output - Codegen itself passes
deno check main.ts,deno lint,deno fmt --check - AzureNormalizer handles allOf, oneOf/anyOf, and discriminator expansion correctly
- Known problematic specs/resources are excluded (see old code's exclude lists)
- CI jobs added (
azure-check,azure-lockfile)
Implementation Order (suggested)
_lib/azure.tsgenerator — self-contained, testable- Path parser —
parseEndpointPath()with tests - AzureNormalizer — start basic (allOf/type inference), then add discriminators
- Pipeline — schema fetching, spec parsing, resource discovery
- Model generator — should be straightforward once pipeline produces right data
- Wire up CLI/commands/CI — mechanical, same pattern as AWS/GCP
Automoved by swampadmin from GitHub issue #25
Open
No activity in this phase yet.
Sign in to post a ripple.