Draft
Support remote URLs for extension bundle zip installs#9417
Conversation
|
Azure Pipelines: 20 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Co-authored-by: JeffreyCA <9157833+JeffreyCA@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add support for remote URLs for extension bundle zip installs
Support remote URLs for extension bundle zip installs
Aug 3, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Adds direct HTTP(S) installation of self-contained extension bundles while preserving the existing local bundle validation and installation flow.
Changes:
- Detects remote
.zipbundle URLs and downloads them through the injected HTTP transport. - Tracks and cleans downloaded archives alongside extracted bundle directories.
- Updates bundle documentation, help text, and unit tests for remote scenarios.
Show a summary per file
| File | Description |
|---|---|
cli/azd/cmd/extension.go |
Implements remote bundle detection, downloading, naming, errors, and cleanup. |
cli/azd/cmd/extension_bundle_test.go |
Tests URL detection, remote downloads, invalid bundles, and cleanup. |
cli/azd/cmd/extension_test.go |
Updates constructor coverage for the new transport dependency. |
cli/azd/docs/extensions/extension-resolution-and-versioning.md |
Documents remote bundle installation, lifecycle, and trust considerations. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Balanced
| // returns its path. The temporary file is recorded on the action so | ||
| // cleanupBundleInstall removes it whether the install succeeds or fails. | ||
| func (a *extensionInstallAction) downloadBundle(ctx context.Context, bundleUrl string) (string, error) { | ||
| stepMessage := fmt.Sprintf("Downloading bundle %s", output.WithHighLightFormat(bundleUrl)) |
| ### Trust model | ||
|
|
||
| Bundles run arbitrary extension binaries on your machine. The embedded `sha256` checksums protect the **integrity** of each artifact within the bundle (they guarantee the bytes were not altered after packing), but bundles are **not signed** — there is no verification of the publisher's identity. Only install bundles you obtained from a source you trust. | ||
| Bundles run arbitrary extension binaries on your machine. The embedded `sha256` checksums protect the **integrity** of each artifact within the bundle (they guarantee the bytes were not altered after packing), but bundles are **not signed** — there is no verification of the publisher's identity. Only install bundles you obtained from a source you trust, and prefer `https` URLs when installing a remote bundle. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Installing a self-contained extension bundle previously required downloading the
.zipfirst.azd extension installnow accepts anhttp(s)URL, so preview/internal builds can be shared as a single link.The URL is downloaded to a temporary file and then runs through the same path as a local bundle — extraction,
registry.jsonvalidation, ephemeral source registration, artifact checksum validation, and re-pointing the installed extension to the reservedbundlesource.Changes (
cli/azd/cmd/extension.go)isBundleArgnow also matches a singlehttp(s)URL whose path ends in.zip(newisRemoteBundleArg). Detection parses the URL and inspects only its path, so query strings (e.g. SAS tokens) don't break it, and no file system access is needed.prepareBundleInstallaccepts a local path or URL; for URLs it calls the newdownloadBundle, which streams the response to a temp file over an azcore pipeline using the injectedpolicy.Transporter(already registered inregisterCommonDependencies), behind aDownloading bundle <url>step..zipis recorded on the action immediately after creation, socleanupBundleInstallremoves it on success and on failure, alongside the extraction directory and transient source.200responses surface asfailed to download bundle from <url>: ...(the latter as anErrorWithSuggestionrecommending a local-path fallback), while a downloaded.zipthat isn't a bundle still fails with the existingbundle does not contain a registry.json at its rootguidance.Behavior
install ./my-ext.zipinstall https://.../my-ext.zipfailed to find extensionfailed to download bundle from <url>: server responded with status 404+ suggestion.zipwithoutregistry.jsonbundle does not contain a registry.json at its root+ suggestion.zipremovedTests & docs
.zipfixture was extracted into a shared helper.cli/azd/docs/extensions/extension-resolution-and-versioning.mddocuments the URL form, the added download/cleanup steps, and a trust-model note preferringhttps; theazd extension installlong help text was updated to match.