Make extension registry updates resilient to coordinated multi-extension version bumps#8927
Make extension registry updates resilient to coordinated multi-extension version bumps#8927JeffreyCA wants to merge 4 commits into
Conversation
Add a --no-dependencies flag to `azd extension install` and cross-dependency registry validation so parallel per-extension release pipelines no longer fail at the "Refresh Fig/Usage snapshots" step when interdependent extensions are bumped together. The snapshot step installs every extension from registry.json through the full dependency-resolving path, but each pipeline rewrites only its own entry against main, so the registry is transiently inconsistent during a coordinated bump. --no-dependencies installs only the named extension, without resolving or installing declared dependencies and without enforcing installed-dependency constraints, on both the fresh-install and reinstall/upgrade paths. The snapshot helper uses it; a normal install is unchanged. Nothing is dropped from the snapshot because every binaried dependency is also a top-level registry entry. Registry validation now checks every declared dependency against published versions using the installer's constraint matcher: an unsatisfiable constraint is an error, an absent dependency id is a warning. A new TestRegistryFileIsValid gate catches inconsistency at PR time instead of inside a snapshot test.
bfe3d50 to
351477d
Compare
351477d to
9d8fb90
Compare
9d8fb90 to
edf5fc4
Compare
a16ac44 to
099e74c
Compare
There was a problem hiding this comment.
Pull request overview
Improves reliability of coordinated azd extension releases by (1) allowing extension installs that skip dependency resolution for snapshot generation, and (2) validating registry dependency constraints so unsatisfiable pins are caught in PR CI rather than later during install/snapshot tests.
Changes:
- Added
--no-dependenciestoazd extension installand plumbed it through install + upgrade paths (SkipDependencies) to bypass dependency install + constraint checks when requested. - Extended registry validation to verify dependency constraints are satisfiable against versions published in the same registry, and added a production-registry validation test.
- Updated docs and regenerated Fig/Usage snapshots; added a workflow gate for
registry.jsonPRs.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/pkg/extensions/validate_registry.go | Builds an index of published versions and validates declared dependencies against satisfiable constraints. |
| cli/azd/pkg/extensions/validate_registry_test.go | Adds unit tests covering satisfied/unsatisfiable/absent/empty dependency-constraint cases. |
| cli/azd/pkg/extensions/registry_files_test.go | Adds a production registry.json validation test with error-only reporting. |
| cli/azd/pkg/extensions/manager.go | Introduces SkipDependencies install/upgrade options and uses them to bypass dependency logic when requested. |
| cli/azd/pkg/extensions/manager_test.go | Adds coverage ensuring dependency skipping works on fresh install, upgrade, and constraint-bypass scenarios. |
| cli/azd/docs/extensions/extension-resolution-and-versioning.md | Documents --no-dependencies behavior in the install algorithm. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-install.snap | Updates usage snapshot to include --no-dependencies. |
| cli/azd/cmd/testdata/TestFigSpec.ts | Updates Fig completion spec to include --no-dependencies. |
| cli/azd/cmd/extension.go | Adds the --no-dependencies flag and wires it into install/upgrade + dependency rendering. |
| cli/azd/cmd/extension_helpers_test.go | Updates snapshot helper to install each extension with --no-dependencies to avoid transient registry inconsistencies. |
| .github/workflows/ext-registry-ci.yml | Adds a CI step to run the new production-registry validation test on registry.json PRs. |
Review details
- Files reviewed: 11/11 changed files
- Comments generated: 3
- Review effort level: Low
- Reword absent-dependency warning: dependencies resolve from the parent's own source, so an absent id is satisfied by publishing it here or having it already installed, not by cross-source resolution. - Fix collectValidationErrors doc: only extension-level errors are id-prefixed; registry-level errors are included as-is. - Make the ext-registry-ci failure message cause-agnostic, since the test fails on any validation error, not only unsatisfiable dependencies.
jongio
left a comment
There was a problem hiding this comment.
Two well-scoped changes that address a real CI reliability problem. The --no-dependencies flag is cleanly threaded through both install and upgrade paths with good test coverage. The registry dependency validation catches genuinely broken states at PR time without blocking routine releases (warning vs error distinction is correct). A few observations:
-
The installInternal check at line 590 (if !opts.SkipDependencies && ...) correctly gates the entire dependency loop, but the earlier check at line 561 (if len(selectedVersion.Artifacts) == 0 && len(selectedVersion.Dependencies) == 0) still runs. This means a dependency-only extension pack (no artifacts, only dependencies) installed with --no-dependencies would still pass this guard and proceed to the artifact download path where it would no-op. That's fine for the stated use case (every extension with a binary is a top-level entry), just noting the interaction.
-
The workflow condition change (if: failure() && (steps.figspec.outcome == 'failure' || steps.usage.outcome == 'failure')) correctly scopes the snapshot guidance message to only fire when the snapshot tests themselves fail, not when the new validation step fails. Good attention to detail.
-
Test coverage is thorough: fresh install, upgrade, constraint-bypass, and the validator's satisfied/unsatisfiable/absent/empty cases are all covered.
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
|
/check-enforcer evaluate |
Fixes #8924
This PR makes extension registry updates resilient when several interdependent extensions are released at the same time.
The problem
When we recently bumped all the
azure.ai.*extension versions together (#8896) and kicked off the per-extension release pipelines in parallel, every pipeline failed at the "Refresh Fig/Usage snapshots" step.That step installs every extension from the in-repo
registry.jsonthrough the full, dependency-resolving install path, and fails on the first error. But each pipeline rewrites only its own registry entry against the current tip ofmain, so the registry under test was transiently inconsistent, producing failures such as:dependency azure.ai.inspector required by azure.ai.agents was not foundinstalled dependency azure.ai.connections version 1.0.0-beta.1 does not satisfy constraint "~0.1.0-preview"We ended up reconciling the registry by hand. This PR closes the two gaps behind that outcome.
Change 1: decouple snapshot generation from dependency resolution
What this means: the ADO extension release pipeline should no longer fail on "Update_Registry - Refresh Fig/Usage snapshots", when the registry is momentarily inconsistent during multi-extension version bumps.
Command snapshots only need each extension's own binary so its commands register. They do not need the registry's dependency graph to be internally consistent.
--no-dependenciesflag toazd extension installthat installs only the named extension, skipping dependency resolution and the installed-dependency constraint check.azd extension install <id>still installs the full dependency graph as before.microsoft.foundrymeta-package contributes no commands.Test pipeline run releasing azure.ai.agents without dependency azure.ai.inspector:
Resulting PR: #8934
Change 2: cross-dependency registry validation
What this means: a genuinely broken registry (a dependency pinned to a version that was never published) is blocked at PR time (not during release pipeline) with a clear, actionable message, instead of slipping through and breaking installs for users. Warnings and mid-rollout publishing are not blocked, so routine releases are unaffected.
Registry validation previously checked per-extension fields but never verified that a declared dependency could actually be resolved, so an inconsistent registry only surfaced as a cryptic install failure inside a snapshot test.
TestRegistryFileIsValidtest runs in theext-registry-ciworkflow on any PR that changesregistry.json, so the automated registry-update PRs are gated on it.Updating microsoft.foundry before all dependencies are updated:
Passing registry consistency but failing snapshot tests:
Successful run:
Behavior at a glance
--no-dependencies; the step no longer depends on registry-wide consistencyazd extension install <id>(no flag), end userazd extension install <id> --no-dependenciesregistry.json, naming the extension, constraint, and available versionsazd x publishwhile a single extension is mid-rolloutTesting
gofmt, andgolangci-lintall pass.