Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/ext-registry-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: ext-registry-ci

on:
pull_request:
paths:
- "cli/azd/extensions/registry.json"
- ".github/workflows/ext-registry-ci.yml"
branches: [main]

# If two events are triggered within a short time in the same PR, cancel the run of the oldest event
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
snapshot-tests:
runs-on: ubuntu-latest
defaults:
run:
working-directory: cli/azd
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "^1.25"
cache-dependency-path: |
cli/azd/go.sum

- name: Build azd
run: go build .

- name: Run FigSpec snapshot test
run: go test ./cmd -v -run TestFigSpec

- name: Run Usage snapshot test
run: go test ./cmd -v -run TestUsage

- name: Check snapshot test results
if: failure()
run: |
echo "::error::Snapshots may be out of date. Run the following locally to update them:"
echo ""
echo " cd cli/azd"
echo " UPDATE_SNAPSHOTS=true go test ./cmd -run 'TestFigSpec|TestUsage'"
exit 1
85 changes: 85 additions & 0 deletions cli/azd/cmd/extension_helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package cmd

import (
"context"
"encoding/json"
"path/filepath"
"testing"

"github.com/azure/azure-dev/cli/azd/test/azdcli"
"github.com/stretchr/testify/require"
)

const (
localSourceName = "local"
)

// extensionListEntry represents an extension entry returned from the extension list command.
type extensionListEntry struct {
ID string `json:"id"`
Version string `json:"version"`
Source string `json:"source"`
}

func installAllExtensions(ctx context.Context, t *testing.T, cli *azdcli.CLI, sourceName string) {
t.Helper()

result, err := cli.RunCommand(ctx, "extension", "list", "--source", sourceName, "--output", "json")
require.NoError(t, err, "failed to list extensions from source %s", sourceName)

var extensions []extensionListEntry
err = json.Unmarshal([]byte(result.Stdout), &extensions)
require.NoError(t, err, "failed to unmarshal extension list")

if len(extensions) == 0 {
t.Logf("No extensions found in source %s to install", sourceName)
return
}

for _, ext := range extensions {
args := []string{"extension", "install", ext.ID, "--source", sourceName}
if ext.Version != "" {
args = append(args, "--version", ext.Version)
}

t.Logf("Installing extension %s@%s", ext.ID, ext.Version)
_, err := cli.RunCommand(ctx, args...)
require.NoErrorf(t, err, "failed to install extension %s from source %s", ext.ID, sourceName)
}
}

func uninstallAllExtensions(ctx context.Context, t *testing.T, cli *azdcli.CLI) {
t.Helper()

t.Log("Uninstalling all extensions")
if _, err := cli.RunCommand(ctx, "extension", "uninstall", "--all"); err != nil {
t.Logf("warning: failed to uninstall extensions: %v", err)
}
}

func addLocalRegistrySource(ctx context.Context, t *testing.T, cli *azdcli.CLI) string {
t.Helper()

registryPath := filepath.Join(azdcli.GetSourcePath(), "extensions", "registry.json")
t.Logf("Adding local registry source '%s' from %s", localSourceName, registryPath)
_, err := cli.RunCommand(
ctx,
"extension", "source", "add",
"-n", localSourceName,
"-t", "file",
"-l", registryPath,
)
require.NoError(t, err, "failed to add local registry source")
return localSourceName
}

func removeLocalExtensionSource(ctx context.Context, t *testing.T, cli *azdcli.CLI) {
t.Helper()

if _, err := cli.RunCommand(ctx, "extension", "source", "remove", localSourceName); err != nil {
t.Logf("warning: failed to remove extension source %s: %v", localSourceName, err)
}
}
22 changes: 22 additions & 0 deletions cli/azd/cmd/figspec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
package cmd

import (
"context"
"testing"
"time"

"github.com/azure/azure-dev/cli/azd/internal/figspec"
"github.com/azure/azure-dev/cli/azd/test/azdcli"
"github.com/azure/azure-dev/cli/azd/test/snapshot"
"github.com/stretchr/testify/require"
)
Expand All @@ -22,6 +25,25 @@ import (
// For Pwsh,
// $env:UPDATE_SNAPSHOTS='true'; go test ./cmd -run TestFigSpec; $env:UPDATE_SNAPSHOTS=$null
func TestFigSpec(t *testing.T) {
configDir := t.TempDir()
t.Setenv("AZD_CONFIG_DIR", configDir)

cli := azdcli.NewCLI(t)

sourceName := addLocalRegistrySource(t.Context(), t, cli)
t.Cleanup(func() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
removeLocalExtensionSource(ctx, t, cli)
})

installAllExtensions(t.Context(), t, cli, sourceName)
t.Cleanup(func() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
uninstallAllExtensions(ctx, t, cli)
})

root := NewRootCmd(false, nil, nil)

builder := figspec.NewSpecBuilder(false)
Expand Down
45 changes: 45 additions & 0 deletions cli/azd/cmd/testdata/TestFigSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ const completionSpec: Fig.Spec = {
name: ['add'],
description: 'Add a component to your project.',
},
{
name: ['ai'],
description: 'Extension for the Foundry Agent Service. (Preview)',
subcommands: [
{
name: ['agent'],
description: 'Extension for the Foundry Agent Service. (Preview)',
},
],
},
{
name: ['auth'],
description: 'Authenticate with Azure.',
Expand Down Expand Up @@ -269,6 +279,10 @@ const completionSpec: Fig.Spec = {
},
],
},
{
name: ['coding-agent'],
description: 'This extension configures GitHub Copilot Coding Agent access to Azure',
},
{
name: ['completion'],
description: 'Generate shell completion scripts.',
Expand Down Expand Up @@ -346,6 +360,10 @@ const completionSpec: Fig.Spec = {
},
],
},
{
name: ['demo'],
description: 'This extension provides examples of the AZD extension framework.',
},
{
name: ['deploy'],
description: 'Deploy your project code to Azure.',
Expand Down Expand Up @@ -656,6 +674,7 @@ const completionSpec: Fig.Spec = {
],
args: {
name: 'extension-id',
generators: azdGenerators.listExtensions,
},
},
{
Expand Down Expand Up @@ -1486,6 +1505,10 @@ const completionSpec: Fig.Spec = {
name: ['version'],
description: 'Print the version number of Azure Developer CLI.',
},
{
name: ['x'],
description: 'This extension provides a set of tools for AZD extension developers to test and debug their extensions.',
},
{
name: ['help'],
description: 'Help about any command',
Expand All @@ -1494,6 +1517,16 @@ const completionSpec: Fig.Spec = {
name: ['add'],
description: 'Add a component to your project.',
},
{
name: ['ai'],
description: 'Extension for the Foundry Agent Service. (Preview)',
subcommands: [
{
name: ['agent'],
description: 'Extension for the Foundry Agent Service. (Preview)',
},
],
},
{
name: ['auth'],
description: 'Authenticate with Azure.',
Expand All @@ -1508,6 +1541,10 @@ const completionSpec: Fig.Spec = {
},
],
},
{
name: ['coding-agent'],
description: 'This extension configures GitHub Copilot Coding Agent access to Azure',
},
{
name: ['completion'],
description: 'Generate shell completion scripts.',
Expand Down Expand Up @@ -1564,6 +1601,10 @@ const completionSpec: Fig.Spec = {
},
],
},
{
name: ['demo'],
description: 'This extension provides examples of the AZD extension framework.',
},
{
name: ['deploy'],
description: 'Deploy your project code to Azure.',
Expand Down Expand Up @@ -1780,6 +1821,10 @@ const completionSpec: Fig.Spec = {
name: ['version'],
description: 'Print the version number of Azure Developer CLI.',
},
{
name: ['x'],
description: 'This extension provides a set of tools for AZD extension developers to test and debug their extensions.',
},
],
},
],
Expand Down
2 changes: 1 addition & 1 deletion cli/azd/cmd/testdata/TestUsage-azd-ai-agent.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

This extension provides custom commands for working with agents using Azure Developer CLI.
Extension for the Foundry Agent Service. (Preview)

Usage
azd ai agent [flags]
Expand Down
4 changes: 2 additions & 2 deletions cli/azd/cmd/testdata/TestUsage-azd-ai.snap
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

This extension provides custom commands for building AI applications using Azure Developer CLI.
Extension for the Foundry Agent Service. (Preview)

Usage
azd ai [command]

Available Commands
builder : This extension provides custom commands for building AI applications using Azure Developer CLI.
agent : Extension for the Foundry Agent Service. (Preview)

Global Flags
-C, --cwd string : Sets the current working directory.
Expand Down
16 changes: 16 additions & 0 deletions cli/azd/cmd/testdata/TestUsage-azd-demo.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

This extension provides examples of the AZD extension framework.

Usage
azd demo [flags]

Global Flags
-C, --cwd string : Sets the current working directory.
--debug : Enables debugging and diagnostics logging.
--docs : Opens the documentation for azd demo in your web browser.
-h, --help : Gets help for demo.
--no-prompt : Accepts the default value instead of prompting, or it fails if there is no default.

Find a bug? Want to let us know how we're doing? Fill out this brief survey: https://aka.ms/azure-dev/hats.


50 changes: 28 additions & 22 deletions cli/azd/cmd/testdata/TestUsage-azd.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,42 @@ Usage

Commands
Getting started
init : Initialize a new application.
up : Provision and deploy your project to Azure with a single command.
init : Initialize a new application.
up : Provision and deploy your project to Azure with a single command.

Create and manage Azure resources
auth : Authenticate with Azure.
deploy : Deploy your project code to Azure.
down : Delete your project's Azure resources.
provision : Provision Azure resources for your project.
publish : Publish a service to a container registry.
auth : Authenticate with Azure.
deploy : Deploy your project code to Azure.
down : Delete your project's Azure resources.
provision : Provision Azure resources for your project.
publish : Publish a service to a container registry.

Manage and show settings
completion : Generate shell completion scripts.
config : Manage azd configurations (ex: default Azure subscription, location).
env : Manage environments (ex: default environment, environment variables).
show : Display information about your project and its resources.
version : Print the version number of Azure Developer CLI.
completion : Generate shell completion scripts.
config : Manage azd configurations (ex: default Azure subscription, location).
env : Manage environments (ex: default environment, environment variables).
show : Display information about your project and its resources.
version : Print the version number of Azure Developer CLI.

Beta commands
add : Add a component to your project.
extension : Manage azd extensions.
hooks : Develop, test and run hooks for a project.
infra : Manage your Infrastructure as Code (IaC).
monitor : Monitor a deployed project.
package : Packages the project's code to be deployed to Azure.
pipeline : Manage and configure your deployment pipelines.
restore : Restores the project's dependencies.
template : Find and view template details.
add : Add a component to your project.
extension : Manage azd extensions.
hooks : Develop, test and run hooks for a project.
infra : Manage your Infrastructure as Code (IaC).
monitor : Monitor a deployed project.
package : Packages the project's code to be deployed to Azure.
pipeline : Manage and configure your deployment pipelines.
restore : Restores the project's dependencies.
template : Find and view template details.

Enabled alpha commands
mcp : Manage Model Context Protocol (MCP) server. (Alpha)
mcp : Manage Model Context Protocol (MCP) server. (Alpha)

Enabled extensions commands
ai : Extension for the Foundry Agent Service. (Preview)
coding-agent : This extension configures GitHub Copilot Coding Agent access to Azure
demo : This extension provides examples of the AZD extension framework.
x : This extension provides a set of tools for AZD extension developers to test and debug their extensions.

Flags
-C, --cwd string : Sets the current working directory.
Expand Down
Loading
Loading