Skip to content

Support remote URLs for extension bundle zip installs - #9417

Draft
JeffreyCA with Copilot wants to merge 2 commits into
mainfrom
copilot/add-remote-url-support
Draft

Support remote URLs for extension bundle zip installs#9417
JeffreyCA with Copilot wants to merge 2 commits into
mainfrom
copilot/add-remote-url-support

Conversation

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Installing a self-contained extension bundle previously required downloading the .zip first. azd extension install now accepts an http(s) URL, so preview/internal builds can be shared as a single link.

azd extension install https://example.com/builds/my-ext_1.0.0.zip

The URL is downloaded to a temporary file and then runs through the same path as a local bundle — extraction, registry.json validation, ephemeral source registration, artifact checksum validation, and re-pointing the installed extension to the reserved bundle source.

Changes (cli/azd/cmd/extension.go)

  • Argument detectionisBundleArg now also matches a single http(s) URL whose path ends in .zip (new isRemoteBundleArg). 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.
  • DownloadprepareBundleInstall accepts a local path or URL; for URLs it calls the new downloadBundle, which streams the response to a temp file over an azcore pipeline using the injected policy.Transporter (already registered in registerCommonDependencies), behind a Downloading bundle <url> step.
  • Cleanup — the temp .zip is recorded on the action immediately after creation, so cleanupBundleInstall removes it on success and on failure, alongside the extraction directory and transient source.
  • Error separation — transport errors and non-200 responses surface as failed to download bundle from <url>: ... (the latter as an ErrorWithSuggestion recommending a local-path fallback), while a downloaded .zip that isn't a bundle still fails with the existing bundle does not contain a registry.json at its root guidance.
  • Naming — the transient source name and progress messages derive from the URL's file name rather than the random temp file name.

Behavior

Scenario Before After
install ./my-ext.zip Installs Unchanged
install https://.../my-ext.zip failed to find extension Downloads, validates, installs
Remote 404 / unreachable n/a failed to download bundle from <url>: server responded with status 404 + suggestion
Remote .zip without registry.json n/a bundle does not contain a registry.json at its root + suggestion
Temp files after success/failure Extraction dir removed Extraction dir and downloaded .zip removed

Tests & docs

  • Unit tests cover URL detection, remote install success (mock HTTP serving real bundle bytes), download failure, invalid remote bundle contents, and temp-file cleanup in each case. The existing not-a-bundle .zip fixture was extracted into a shared helper.
  • cli/azd/docs/extensions/extension-resolution-and-versioning.md documents the URL form, the added download/cleanup steps, and a trust-model note preferring https; the azd extension install long help text was updated to match.

@azure-pipelines

Copy link
Copy Markdown
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
Copilot AI requested a review from JeffreyCA August 3, 2026 23:19
@JeffreyCA
JeffreyCA requested a review from Copilot August 3, 2026 23:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 .zip bundle 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

Comment thread cli/azd/cmd/extension.go
// 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support remote URLs for extension bundle zip installs

3 participants