From a79b5eb4d28b03768b0b1535a816e016e5a8ade5 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 14:56:10 +0000 Subject: [PATCH 01/38] Add Azure Logic Apps Standard extension --- .../azure.logicappsstandard/CHANGELOG.md | 3 + .../azure.logicappsstandard/README.md | 3 + .../azure.logicappsstandard/build.ps1 | 78 +++++ .../azure.logicappsstandard/build.sh | 66 ++++ .../azure.logicappsstandard/extension.yaml | 11 + .../extensions/azure.logicappsstandard/go.mod | 105 ++++++ .../extensions/azure.logicappsstandard/go.sum | 316 ++++++++++++++++++ .../internal/cmd/listen.go | 17 + .../internal/cmd/root.go | 29 ++ .../framework_service_logicappsstandard.go | 192 +++++++++++ ...ramework_service_logicappsstandard_test.go | 294 ++++++++++++++++ .../azure.logicappsstandard/main.go | 14 + .../azure.logicappsstandard/version.txt | 1 + 13 files changed, 1129 insertions(+) create mode 100644 cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md create mode 100644 cli/azd/extensions/azure.logicappsstandard/README.md create mode 100644 cli/azd/extensions/azure.logicappsstandard/build.ps1 create mode 100644 cli/azd/extensions/azure.logicappsstandard/build.sh create mode 100644 cli/azd/extensions/azure.logicappsstandard/extension.yaml create mode 100644 cli/azd/extensions/azure.logicappsstandard/go.mod create mode 100644 cli/azd/extensions/azure.logicappsstandard/go.sum create mode 100644 cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go create mode 100644 cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go create mode 100644 cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go create mode 100644 cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go create mode 100644 cli/azd/extensions/azure.logicappsstandard/main.go create mode 100644 cli/azd/extensions/azure.logicappsstandard/version.txt diff --git a/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md new file mode 100644 index 00000000000..b88d613cce0 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md @@ -0,0 +1,3 @@ +# Release History + +## 0.0.1 - Initial Version \ No newline at end of file diff --git a/cli/azd/extensions/azure.logicappsstandard/README.md b/cli/azd/extensions/azure.logicappsstandard/README.md new file mode 100644 index 00000000000..aa8e9a306a2 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/README.md @@ -0,0 +1,3 @@ +# Azure Logic Apps Standard extension + +Azure Developer CLI (azd) extension for packaging Logic Apps Standard projects, including support for custom code projects. diff --git a/cli/azd/extensions/azure.logicappsstandard/build.ps1 b/cli/azd/extensions/azure.logicappsstandard/build.ps1 new file mode 100644 index 00000000000..5ceb60a8bbc --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/build.ps1 @@ -0,0 +1,78 @@ +# Ensure script fails on any error +$ErrorActionPreference = 'Stop' + +# Get the directory of the script +$EXTENSION_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path + +# Change to the script directory +Set-Location -Path $EXTENSION_DIR + +# Create a safe version of EXTENSION_ID replacing dots with dashes +$EXTENSION_ID_SAFE = $env:EXTENSION_ID -replace '\.', '-' + +# Define output directory +$OUTPUT_DIR = if ($env:OUTPUT_DIR) { $env:OUTPUT_DIR } else { Join-Path $EXTENSION_DIR "bin" } + +# Create output directory if it doesn't exist +if (-not (Test-Path -Path $OUTPUT_DIR)) { + New-Item -ItemType Directory -Path $OUTPUT_DIR | Out-Null +} + +# Get Git commit hash and build date +$COMMIT = git rev-parse HEAD +if ($LASTEXITCODE -ne 0) { + Write-Host "Error: Failed to get git commit hash" + exit 1 +} +$BUILD_DATE = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ") + +# List of OS and architecture combinations +if ($env:EXTENSION_PLATFORM) { + $PLATFORMS = @($env:EXTENSION_PLATFORM) +} +else { + $PLATFORMS = @( + "windows/amd64", + "windows/arm64", + "darwin/amd64", + "darwin/arm64", + "linux/amd64", + "linux/arm64" + ) +} + +$APP_PATH = "$env:EXTENSION_ID/internal/cmd" + +# Loop through platforms and build +foreach ($PLATFORM in $PLATFORMS) { + $OS, $ARCH = $PLATFORM -split '/' + + $OUTPUT_NAME = Join-Path $OUTPUT_DIR "$EXTENSION_ID_SAFE-$OS-$ARCH" + + if ($OS -eq "windows") { + $OUTPUT_NAME += ".exe" + } + + Write-Host "Building for $OS/$ARCH..." + + # Delete the output file if it already exists + if (Test-Path -Path $OUTPUT_NAME) { + Remove-Item -Path $OUTPUT_NAME -Force + } + + # Set environment variables for Go build + $env:GOOS = $OS + $env:GOARCH = $ARCH + + go build ` + -ldflags="-X '$APP_PATH.Version=$env:EXTENSION_VERSION' -X '$APP_PATH.Commit=$COMMIT' -X '$APP_PATH.BuildDate=$BUILD_DATE'" ` + -o $OUTPUT_NAME + + if ($LASTEXITCODE -ne 0) { + Write-Host "An error occurred while building for $OS/$ARCH" + exit 1 + } +} + +Write-Host "Build completed successfully!" +Write-Host "Binaries are located in the $OUTPUT_DIR directory." diff --git a/cli/azd/extensions/azure.logicappsstandard/build.sh b/cli/azd/extensions/azure.logicappsstandard/build.sh new file mode 100644 index 00000000000..f1a995ec5e9 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/build.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# Get the directory of the script +EXTENSION_DIR="$(cd "$(dirname "$0")" && pwd)" + +# Change to the script directory +cd "$EXTENSION_DIR" || exit + +# Create a safe version of EXTENSION_ID replacing dots with dashes +EXTENSION_ID_SAFE="${EXTENSION_ID//./-}" + +# Define output directory +OUTPUT_DIR="${OUTPUT_DIR:-$EXTENSION_DIR/bin}" + +# Create output and target directories if they don't exist +mkdir -p "$OUTPUT_DIR" + +# Get Git commit hash and build date +COMMIT=$(git rev-parse HEAD) +BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) + +# List of OS and architecture combinations +if [ -n "$EXTENSION_PLATFORM" ]; then + PLATFORMS=("$EXTENSION_PLATFORM") +else + PLATFORMS=( + "windows/amd64" + "windows/arm64" + "darwin/amd64" + "darwin/arm64" + "linux/amd64" + "linux/arm64" + ) +fi + +APP_PATH="$EXTENSION_ID/internal/cmd" + +# Loop through platforms and build +for PLATFORM in "${PLATFORMS[@]}"; do + OS=$(echo "$PLATFORM" | cut -d'/' -f1) + ARCH=$(echo "$PLATFORM" | cut -d'/' -f2) + + OUTPUT_NAME="$OUTPUT_DIR/$EXTENSION_ID_SAFE-$OS-$ARCH" + + if [ "$OS" = "windows" ]; then + OUTPUT_NAME+='.exe' + fi + + echo "Building for $OS/$ARCH..." + + # Delete the output file if it already exists + [ -f "$OUTPUT_NAME" ] && rm -f "$OUTPUT_NAME" + + # Set environment variables for Go build + GOOS=$OS GOARCH=$ARCH go build \ + -ldflags="-X '$APP_PATH.Version=$EXTENSION_VERSION' -X '$APP_PATH.Commit=$COMMIT' -X '$APP_PATH.BuildDate=$BUILD_DATE'" \ + -o "$OUTPUT_NAME" + + if [ $? -ne 0 ]; then + echo "An error occurred while building for $OS/$ARCH" + exit 1 + fi +done + +echo "Build completed successfully!" +echo "Binaries are located in the $OUTPUT_DIR directory." diff --git a/cli/azd/extensions/azure.logicappsstandard/extension.yaml b/cli/azd/extensions/azure.logicappsstandard/extension.yaml new file mode 100644 index 00000000000..567bae27402 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/extension.yaml @@ -0,0 +1,11 @@ +# yaml-language-server: $schema=../extension.schema.json +id: azure.logicappsstandard +namespace: logicappsstandard +displayName: Azure Logic Apps Standard +description: Extension for packaging Logic Apps Standard projects, including support for custom code projects +usage: Use 'language: logicappsstandard' in your service configuration to package the service as a Logic Apps Standard project. Use the customCodeProject property to specify a custom code project to include in the package. E.g. 'customCodeProject: Functions/Functions.csproj' +# NOTE: Make sure version.txt is in sync with this version. +version: 0.0.1 +language: go +capabilities: + - framework-service-provider \ No newline at end of file diff --git a/cli/azd/extensions/azure.logicappsstandard/go.mod b/cli/azd/extensions/azure.logicappsstandard/go.mod new file mode 100644 index 00000000000..490ccd867a9 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/go.mod @@ -0,0 +1,105 @@ +module azure.logicappsstandard + +go 1.26.1 + +require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 + github.com/azure/azure-dev/cli/azd v1.24.2 + github.com/fatih/color v1.19.0 + github.com/spf13/cobra v1.10.2 +) + +require ( + github.com/AlecAivazis/survey/v2 v2.3.7 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b // indirect + github.com/alecthomas/chroma/v2 v2.23.1 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/aymerick/douceur v0.2.0 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/braydonk/yaml v0.9.0 // indirect + github.com/buger/goterm v1.0.4 // indirect + github.com/buger/jsonparser v1.1.2 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/charmbracelet/colorprofile v0.4.3 // indirect + github.com/charmbracelet/glamour v1.0.0 // indirect + github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect + github.com/charmbracelet/x/ansi v0.11.7 // indirect + github.com/charmbracelet/x/cellbuf v0.0.15 // indirect + github.com/charmbracelet/x/exp/slice v0.0.0-20260422141420-a6cbdff8a7e2 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect + github.com/cli/browser v1.3.0 // indirect + github.com/clipperhouse/displaywidth v0.11.0 // indirect + github.com/clipperhouse/uax29/v2 v2.7.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dlclark/regexp2 v1.12.0 // indirect + github.com/drone/envsubst v1.0.3 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/gofrs/flock v0.13.0 // indirect + github.com/golang-jwt/jwt/v5 v5.3.1 // indirect + github.com/golobby/container/v3 v3.3.2 // indirect + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/css v1.0.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/invopop/jsonschema v0.14.0 // indirect + github.com/jmespath-community/go-jmespath v1.1.1 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/lucasb-eyer/go-colorful v1.4.0 // indirect + github.com/mark3labs/mcp-go v0.49.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.21 // indirect + github.com/mattn/go-runewidth v0.0.23 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/microcosm-cc/bluemonday v1.0.27 // indirect + github.com/microsoft/ApplicationInsights-Go v0.4.4 // indirect + github.com/microsoft/go-deviceid v1.0.0 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.16.0 // indirect + github.com/nathan-fiscaletti/consolesize-go v0.0.0-20260406063853-3bac975de715 // indirect + github.com/pb33f/ordered-map/v2 v2.3.1 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect + github.com/sethvargo/go-retry v0.3.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/stretchr/testify v1.11.1 // indirect + github.com/theckman/yacspin v0.13.12 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect + github.com/yuin/goldmark v1.8.2 // indirect + github.com/yuin/goldmark-emoji v1.0.6 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect + golang.org/x/crypto v0.50.0 // indirect + golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/time v0.15.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 // indirect + google.golang.org/grpc v1.80.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/cli/azd/extensions/azure.logicappsstandard/go.sum b/cli/azd/extensions/azure.logicappsstandard/go.sum new file mode 100644 index 00000000000..4735d1e22a8 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/go.sum @@ -0,0 +1,316 @@ +code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= +github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= +github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 h1:jHb/wfvRikGdxMXYV3QG/SzUOPYN9KEUUuC0Yd0/vC0= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1/go.mod h1:pzBXCYn05zvYIrwLgtK8Ap8QcjRg+0i76tMQdWN6wOk= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0 h1:2qsIIvxVT+uE6yrNldntJKlLRgxGbZ85kgtz5SNBhMw= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0/go.mod h1:AW8VEadnhw9xox+VaVd9sP7NjzOAnaZBLRH6Tq3cJ38= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0 h1:nnQ9vXH039UrEFxi08pPuZBE7VfqSJt343uJLw0rhWI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0/go.mod h1:4YIVtzMFVsPwBvitCDX7J9sqthSj43QD1sP6fYc1egc= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 h1:wxQx2Bt4xzPIKvW59WQf1tJNx/ZZKPfN+EhPX3Z6CYY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0/go.mod h1:TpiwjwnW/khS0LKs4vW5UmmT9OWcxaveS8U7+tlknzo= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 h1:/g8S6wk65vfC6m3FIxJ+i5QDyN9JWwXI8Hb0Img10hU= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0/go.mod h1:gpl+q95AzZlKVI3xSoseF9QPrypk0hQqBiJYeB/cR/I= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1 h1:edShSHV3DV90+kt+CMaEXEzR9QF7wFrPJxVGz2blMIU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= +github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b h1:g9SuFmxM/WucQFKTMSP+irxyf5m0RiUJreBDhGI6jSA= +github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b/go.mod h1:XjvqMUpGd3Xn9Jtzk/4GEBCSoBX0eB2RyriXgne0IdM= +github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= +github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY= +github.com/alecthomas/chroma/v2 v2.23.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o= +github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= +github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= +github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/azure/azure-dev/cli/azd v1.24.2 h1:Y/m9CrjhgNgFoolMU0HmDn358eWB8Cpmh/G2F+5urAQ= +github.com/azure/azure-dev/cli/azd v1.24.2/go.mod h1:YANepMw36aWA8/mQyXau6JCAG84oK0ZgfvLF8rN5asU= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= +github.com/braydonk/yaml v0.9.0 h1:ewGMrVmEVpsm3VwXQDR388sLg5+aQ8Yihp6/hc4m+h4= +github.com/braydonk/yaml v0.9.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4= +github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY= +github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= +github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= +github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= +github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= +github.com/charmbracelet/glamour v1.0.0 h1:AWMLOVFHTsysl4WV8T8QgkQ0s/ZNZo7CiE4WKhk8l08= +github.com/charmbracelet/glamour v1.0.0/go.mod h1:DSdohgOBkMr2ZQNhw4LZxSGpx3SvpeujNoXrQyH2hxo= +github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= +github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= +github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI= +github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ= +github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= +github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= +github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30= +github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= +github.com/charmbracelet/x/exp/slice v0.0.0-20260422141420-a6cbdff8a7e2 h1:EXQ7j9kQUGILoSIbxrr1osK9Ca3xqc6EJ7710FIiI3U= +github.com/charmbracelet/x/exp/slice v0.0.0-20260422141420-a6cbdff8a7e2/go.mod h1:vqEfX6xzqW1pKKZUUiFOKg0OQ7bCh54Q2vR/tserrRA= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= +github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo= +github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= +github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= +github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= +github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= +github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8= +github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= +github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= +github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golobby/container/v3 v3.3.2 h1:7u+RgNnsdVlhGoS8gY4EXAG601vpMMzLZlYqSp77Quw= +github.com/golobby/container/v3 v3.3.2/go.mod h1:RDdKpnKpV1Of11PFBe7Dxc2C1k2KaLE4FD47FflAmj0= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= +github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/invopop/jsonschema v0.14.0 h1:MHQqLhvpNUZfw+hM3AZDYK7jxO8FZoQeQM77g8iyZjg= +github.com/invopop/jsonschema v0.14.0/go.mod h1:ygm6C2EaVNMBDPpaPlnOA2pFAxBnxGjFlMZABxm9n2I= +github.com/jmespath-community/go-jmespath v1.1.1 h1:bFikPhsi/FdmlZhVgSCd2jj1e7G/rw+zyQfyg5UF+L4= +github.com/jmespath-community/go-jmespath v1.1.1/go.mod h1:4gOyFJsR/Gk+05RgTKYrifT7tBPWD8Lubtb5jRrfy9I= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= +github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= +github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mark3labs/mcp-go v0.49.0 h1:7Ssx4d7/T86qnWoJIdye7wEEvUzv39UIbnZb/FqUZMY= +github.com/mark3labs/mcp-go v0.49.0/go.mod h1:BflTAZAzXlrTpiO44gmjMu89n2FO56rJ9m31fp4zd5k= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs= +github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= +github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= +github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= +github.com/microsoft/ApplicationInsights-Go v0.4.4 h1:G4+H9WNs6ygSCe6sUyxRc2U81TI5Es90b2t/MwX5KqY= +github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U= +github.com/microsoft/go-deviceid v1.0.0 h1:i5AQ654Xk9kfvwJeKQm3w2+eT1+ImBDVEpAR0AjpP40= +github.com/microsoft/go-deviceid v1.0.0/go.mod h1:KY13FeVdHkzD8gy+6T8+kVmD/7RMpTaWW75K+T4uZWg= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/nathan-fiscaletti/consolesize-go v0.0.0-20260406063853-3bac975de715 h1:FiSC3sz/k2SYB32YJ1bLlBVB7Li0N7n6jcYa9Knq/60= +github.com/nathan-fiscaletti/consolesize-go v0.0.0-20260406063853-3bac975de715/go.mod h1:DQpEqvLUU3b35AJUVu5P6LFn/RY3qj4WtMjvrcE8gto= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pb33f/ordered-map/v2 v2.3.1 h1:5319HDO0aw4DA4gzi+zv4FXU9UlSs3xGZ40wcP1nBjY= +github.com/pb33f/ordered-map/v2 v2.3.1/go.mod h1:qxFQgd0PkVUtOMCkTapqotNgzRhMPL7VvaHKbd1HnmQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= +github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= +github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= +github.com/theckman/yacspin v0.13.12 h1:CdZ57+n0U6JMuh2xqjnjRq5Haj6v1ner2djtLQRzJr4= +github.com/theckman/yacspin v0.13.12/go.mod h1:Rd2+oG2LmQi5f3zC3yeZAOl245z8QOvrH4OPOJNZxLg= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= +github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= +github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U= +go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 h1:XF8+t6QQiS0o9ArVan/HW8Q7cycNPGsJf6GA2nXxYAg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go new file mode 100644 index 00000000000..238b2322223 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package cmd + +import ( + "github.com/azure/azure-dev/cli/azd/pkg/azdext" + + "azure.logicappsstandard/internal/project" +) + +// configureListen is called by NewListenCommand to register event handlers. +func configureListen(host *azdext.ExtensionHost) { + host.WithFrameworkService("logicappsstandard", func() azdext.FrameworkServiceProvider { + return project.NewLogicAppsStandardPackagingFrameworkServiceProvider() + }) +} diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go new file mode 100644 index 00000000000..b33ca85d993 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package cmd + +import ( + "github.com/azure/azure-dev/cli/azd/pkg/azdext" + "github.com/spf13/cobra" +) + +const ( + extensionID = "azure.logicappsstandard" + version = "0.0.1" +) + +func NewRootCommand() *cobra.Command { + rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{ + Name: extensionID, + Version: version, + Short: "Extension for packaging Logic Apps Standard projects, including support for custom code projects", + }) + + // Standard lifecycle, metadata, and version commands + rootCmd.AddCommand(azdext.NewListenCommand(configureListen)) + rootCmd.AddCommand(azdext.NewMetadataCommand("1.0", extensionID, NewRootCommand)) + rootCmd.AddCommand(azdext.NewVersionCommand(extensionID, version, &extCtx.OutputFormat)) + + return rootCmd +} diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go new file mode 100644 index 00000000000..adabb63fb3f --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -0,0 +1,192 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package project + +import ( + "context" + "fmt" + "os" + "path/filepath" + + "github.com/azure/azure-dev/cli/azd/pkg/azdext" +) + +// Ensure LogicAppsStandardPackagingFrameworkServiceProvider implements FrameworkServiceProvider interface +var _ azdext.FrameworkServiceProvider = &LogicAppsStandardPackagingFrameworkServiceProvider{} + +// LogicAppsStandardPackagingFrameworkServiceProvider introduces the custom language 'logicappsstandard' to the framework service provider, +// enabling it to handle packaging for Logic Apps Standard projects, including those with custom code components. +type LogicAppsStandardPackagingFrameworkServiceProvider struct { + serviceConfig *azdext.ServiceConfig +} + +func NewLogicAppsStandardPackagingFrameworkServiceProvider() azdext.FrameworkServiceProvider { + return &LogicAppsStandardPackagingFrameworkServiceProvider{} +} + +// Initialize initializes the framework service provider with service configuration +func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Initialize(ctx context.Context, serviceConfig *azdext.ServiceConfig) error { + fmt.Printf("Initializing Logic Apps Standard framework for service: %s\n", serviceConfig.GetName()) + p.serviceConfig = serviceConfig + + if hasCustomCodeProjectConfigured(serviceConfig) { + csProjPath, err := p.resolveCustomCodeProjectPath(serviceConfig) + if err != nil { + return err + } + projectInfo, err := os.Stat(csProjPath) + if err != nil { + return fmt.Errorf("custom code project not found at '%s': %w", csProjPath, err) + } + if projectInfo.IsDir() { + return fmt.Errorf("custom code project path '%s' must point to a file", csProjPath) + } + } + + return nil +} + +// Returns dotnet as required external tool if a custom code project is configured +func (p *LogicAppsStandardPackagingFrameworkServiceProvider) RequiredExternalTools( + ctx context.Context, + serviceConfig *azdext.ServiceConfig, +) ([]*azdext.ExternalTool, error) { + if hasCustomCodeProjectConfigured(serviceConfig) { + return []*azdext.ExternalTool{ + { + Name: "dotnet", + InstallUrl: "https://dotnet.microsoft.com/download", + }, + }, nil + } + return nil, nil +} + +// Requirements returns the framework requirements (whether restore/build are needed) +func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Requirements() (*azdext.FrameworkRequirements, error) { + hasCustomCodeProject := p.serviceConfig != nil && hasCustomCodeProjectConfigured(p.serviceConfig) + return &azdext.FrameworkRequirements{ + Package: &azdext.FrameworkPackageRequirements{ + RequireRestore: hasCustomCodeProject, + RequireBuild: hasCustomCodeProject, + }, + }, nil +} + +// Restores the dependencies for the custom code project if specified in the service configuration. +func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Restore( + ctx context.Context, + serviceConfig *azdext.ServiceConfig, + serviceContext *azdext.ServiceContext, + progress azdext.ProgressReporter, +) (*azdext.ServiceRestoreResult, error) { + if hasCustomCodeProjectConfigured(serviceConfig) { + progress("Restoring .NET project dependencies") + csProjPath, err := p.resolveCustomCodeProjectPath(serviceConfig) + if err != nil { + return nil, err + } + if err := runDotNet(ctx, "restore", csProjPath); err != nil { + return nil, fmt.Errorf("restoring custom code project '%s': %w", csProjPath, err) + } + } + return &azdext.ServiceRestoreResult{}, nil +} + +// Builds the custom code project if specified in the service configuration. +func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Build( + ctx context.Context, + serviceConfig *azdext.ServiceConfig, + serviceContext *azdext.ServiceContext, + progress azdext.ProgressReporter, +) (*azdext.ServiceBuildResult, error) { + if hasCustomCodeProjectConfigured(serviceConfig) { + progress("Building .NET project") + csProjPath, err := p.resolveCustomCodeProjectPath(serviceConfig) + if err != nil { + return nil, err + } + if err := runDotNet(ctx, "build", csProjPath, "--configuration", "Release"); err != nil { + return nil, fmt.Errorf("building custom code project '%s': %w", csProjPath, err) + } + } + return &azdext.ServiceBuildResult{}, nil +} + +// Packages the Logic Apps Standard project, including any custom code components, into a deployable artifact. +func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Package( + ctx context.Context, + serviceConfig *azdext.ServiceConfig, + serviceContext *azdext.ServiceContext, + progress azdext.ProgressReporter, +) (*azdext.ServicePackageResult, error) { + progress("Creating Logic Apps Standard deployment package") + + projectDir, err := azdext.GetProjectDir() + if err != nil { + return nil, fmt.Errorf("getting project directory: %w", err) + } + + // Determine the absolute path to the Logic Apps Standard project based on the project directory + // and the relative path specified in the service configuration. + packagePath := filepath.Join(projectDir, serviceConfig.RelativePath) + + // If an output path (dist) is specified, append it to the package path + // This allows for subdirectories like "Workflows" to be the root of the zip + if serviceConfig.OutputPath != "" { + packagePath = filepath.Join(packagePath, serviceConfig.OutputPath) + } + + // Return a DIRECTORY artifact pointing to the project root. + // azd's packaging pipeline will handle creating the zip archive from this directory. + // By specifying an absolute path, azd will use the .funcignore file to exclude unnecessary files from the package. + return &azdext.ServicePackageResult{ + Artifacts: []*azdext.Artifact{ + { + Kind: azdext.ArtifactKind_ARTIFACT_KIND_DIRECTORY, + Location: packagePath, + LocationKind: azdext.LocationKind_LOCATION_KIND_LOCAL, + }, + }, + }, nil +} + +func (p *LogicAppsStandardPackagingFrameworkServiceProvider) resolveCustomCodeProjectPath( + serviceConfig *azdext.ServiceConfig, +) (string, error) { + projectDir, err := azdext.GetProjectDir() + if err != nil { + return "", fmt.Errorf("getting project directory: %w", err) + } + + return filepath.Join( + projectDir, + serviceConfig.RelativePath, + getAdditionalProperty(serviceConfig, "customCodeProject"), + ), nil +} + +// getAdditionalProperty retrieves a custom property from the service configuration's additional properties. +func getAdditionalProperty(serviceConfig *azdext.ServiceConfig, key string) string { + props := serviceConfig.GetAdditionalProperties() + if props == nil { + return "" + } + if v, ok := props.Fields[key]; ok { + return v.GetStringValue() + } + return "" +} + +func hasCustomCodeProjectConfigured(serviceConfig *azdext.ServiceConfig) bool { + return getAdditionalProperty(serviceConfig, "customCodeProject") != "" +} + +// runDotNet executes the dotnet CLI with the given arguments, forwarding output to stdout/stderr. +func runDotNet(ctx context.Context, args ...string) error { + cmd := azdext.ExecCommand(ctx, "dotnet", args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go new file mode 100644 index 00000000000..01cb03a6149 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -0,0 +1,294 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package project + +import ( + "context" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/azure/azure-dev/cli/azd/pkg/azdext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/structpb" +) + +func TestGetAdditionalProperty(t *testing.T) { + t.Run("returns empty for nil additional properties", func(t *testing.T) { + svc := &azdext.ServiceConfig{} + assert.Equal(t, "", getAdditionalProperty(svc, "customCodeProject")) + }) + + t.Run("returns property value when present", func(t *testing.T) { + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + }) + + assert.Equal(t, "Functions/Functions.csproj", getAdditionalProperty(svc, "customCodeProject")) + }) +} + +func TestHasCustomCodeProjectConfigured(t *testing.T) { + t.Run("returns false when customCodeProject is absent", func(t *testing.T) { + assert.False(t, hasCustomCodeProjectConfigured(newServiceConfig("logicApp", "src/logicApp", nil))) + }) + + t.Run("returns true when customCodeProject is present", func(t *testing.T) { + assert.True(t, hasCustomCodeProjectConfigured(newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + }))) + }) +} + +func TestRequiredExternalTools(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + + t.Run("returns nil when custom code is not configured", func(t *testing.T) { + tools, err := provider.RequiredExternalTools(context.Background(), newServiceConfig("logicApp", "src/logicApp", nil)) + require.NoError(t, err) + assert.Nil(t, tools) + }) + + t.Run("returns dotnet when custom code is configured", func(t *testing.T) { + tools, err := provider.RequiredExternalTools(context.Background(), newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + })) + require.NoError(t, err) + require.Len(t, tools, 1) + assert.Equal(t, "dotnet", tools[0].Name) + assert.Equal(t, "https://dotnet.microsoft.com/download", tools[0].InstallUrl) + }) +} + +func TestRequirements(t *testing.T) { + t.Run("disables restore and build when service config is not initialized", func(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + reqs, err := provider.Requirements() + require.NoError(t, err) + require.NotNil(t, reqs.Package) + assert.False(t, reqs.Package.RequireRestore) + assert.False(t, reqs.Package.RequireBuild) + }) + + t.Run("disables restore and build when initialized without customCodeProject", func(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider.serviceConfig = newServiceConfig("logicApp", "src/logicApp", nil) + reqs, err := provider.Requirements() + require.NoError(t, err) + require.NotNil(t, reqs.Package) + assert.False(t, reqs.Package.RequireRestore) + assert.False(t, reqs.Package.RequireBuild) + }) + + t.Run("enables restore and build when customCodeProject is configured", func(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider.serviceConfig = newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + }) + reqs, err := provider.Requirements() + require.NoError(t, err) + require.NotNil(t, reqs.Package) + assert.True(t, reqs.Package.RequireRestore) + assert.True(t, reqs.Package.RequireBuild) + }) +} + +func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { + projectDir := t.TempDir() + createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") + + t.Run("succeeds without customCodeProject and sets serviceConfig", func(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", nil) + + err := provider.Initialize(context.Background(), svc) + require.NoError(t, err) + assert.Equal(t, svc, provider.serviceConfig) + }) + + t.Run("succeeds when custom code project file exists", func(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + }) + + createFile(t, filepath.Join(projectDir, "src/logicApp/Functions/Functions.csproj"), "\n") + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + err := provider.Initialize(context.Background(), svc) + require.NoError(t, err) + }) + }) + + t.Run("fails when custom code project is a directory", func(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions", + }) + + err := os.MkdirAll(filepath.Join(projectDir, "src/logicApp/Functions"), 0o755) + require.NoError(t, err) + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + err := provider.Initialize(context.Background(), svc) + require.Error(t, err) + assert.Contains(t, err.Error(), "must point to a file") + }) + }) + + t.Run("fails when custom code project file is missing", func(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Missing.csproj", + }) + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + err := provider.Initialize(context.Background(), svc) + require.Error(t, err) + assert.Contains(t, err.Error(), "custom code project not found") + }) + }) +} + +func TestPackageUsesProjectAndOutputPaths(t *testing.T) { + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + projectDir := t.TempDir() + createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + result, err := provider.Package(context.Background(), newServiceConfig("logicApp", "src/logicApp", nil), nil, func(string) {}) + require.NoError(t, err) + require.Len(t, result.Artifacts, 1) + + artifact := result.Artifacts[0] + expectedPath := filepath.Join(projectDir, "src/logicApp") + assert.Equal(t, expectedPath, artifact.Location) + assert.Equal(t, azdext.ArtifactKind_ARTIFACT_KIND_DIRECTORY, artifact.Kind) + assert.Equal(t, azdext.LocationKind_LOCATION_KIND_LOCAL, artifact.LocationKind) + }) + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + svc := newServiceConfig("logicApp", "src/logicApp", nil) + svc.OutputPath = "Workflows" + + result, err := provider.Package(context.Background(), svc, nil, func(string) {}) + require.NoError(t, err) + expectedPath := filepath.Join(projectDir, "src/logicApp", "Workflows") + require.NotEmpty(t, result.Artifacts) + assert.Equal(t, expectedPath, result.Artifacts[0].Location) + }) +} + +func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { + projectDir := t.TempDir() + createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") + csprojPath := filepath.Join(projectDir, "src/logicApp/Functions/Functions.csproj") + createFile(t, csprojPath, "\n") + + logFile := filepath.Join(t.TempDir(), "dotnet.log") + fakeBinDir := t.TempDir() + fakeDotnetPath := filepath.Join(fakeBinDir, "dotnet") + createFile(t, fakeDotnetPath, "#!/bin/sh\nprintf '%s\n' \"$*\" >> \"$DOTNET_ARGS_LOG\"\n") + err := os.Chmod(fakeDotnetPath, 0o755) + require.NoError(t, err) + + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + }) + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + withEnv(t, "DOTNET_ARGS_LOG", logFile, func() { + withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() { + _, err := provider.Restore(context.Background(), svc, nil, func(string) {}) + require.NoError(t, err) + _, err = provider.Build(context.Background(), svc, nil, func(string) {}) + require.NoError(t, err) + }) + }) + }) + + contents, err := os.ReadFile(logFile) + require.NoError(t, err) + logLines := strings.Split(strings.TrimSpace(string(contents)), "\n") + require.Len(t, logLines, 2, "expected two dotnet invocations: %q", string(contents)) + + expectedRestore := "restore " + csprojPath + assert.Equal(t, expectedRestore, logLines[0]) + + expectedBuild := "build " + csprojPath + " --configuration Release" + assert.Equal(t, expectedBuild, logLines[1]) +} + +func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) { + logFile := filepath.Join(t.TempDir(), "dotnet.log") + fakeBinDir := t.TempDir() + fakeDotnetPath := filepath.Join(fakeBinDir, "dotnet") + createFile(t, fakeDotnetPath, "#!/bin/sh\nprintf '%s\n' \"$*\" >> \"$DOTNET_ARGS_LOG\"\n") + err := os.Chmod(fakeDotnetPath, 0o755) + require.NoError(t, err) + + provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", nil) + + withEnv(t, "DOTNET_ARGS_LOG", logFile, func() { + withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() { + _, err := provider.Restore(context.Background(), svc, nil, func(string) {}) + require.NoError(t, err) + _, err = provider.Build(context.Background(), svc, nil, func(string) {}) + require.NoError(t, err) + }) + }) + + if _, statErr := os.Stat(logFile); statErr == nil { + contents, readErr := os.ReadFile(logFile) + require.NoError(t, readErr) + assert.Empty(t, strings.TrimSpace(string(contents)), "dotnet should not be invoked when customCodeProject is not configured") + } else { + require.ErrorIs(t, statErr, os.ErrNotExist) + } +} + +func newServiceConfig(name, relativePath string, additionalProps map[string]any) *azdext.ServiceConfig { + svc := &azdext.ServiceConfig{ + Name: name, + RelativePath: relativePath, + } + + if additionalProps != nil { + props, err := structpb.NewStruct(additionalProps) + if err != nil { + panic(err) + } + svc.AdditionalProperties = props + } + + return svc +} + +func withEnv(t *testing.T, key, value string, fn func()) { + t.Helper() + original, existed := os.LookupEnv(key) + err := os.Setenv(key, value) + require.NoError(t, err, "failed to set %s", key) + t.Cleanup(func() { + if !existed { + _ = os.Unsetenv(key) + return + } + _ = os.Setenv(key, original) + }) + + fn() +} + +func createFile(t *testing.T, filePath, content string) { + t.Helper() + err := os.MkdirAll(filepath.Dir(filePath), 0o755) + require.NoError(t, err, "failed creating directory %q", filepath.Dir(filePath)) + err = os.WriteFile(filePath, []byte(content), 0o644) + require.NoError(t, err, "failed writing file %q", filePath) +} diff --git a/cli/azd/extensions/azure.logicappsstandard/main.go b/cli/azd/extensions/azure.logicappsstandard/main.go new file mode 100644 index 00000000000..0f77478c02b --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/main.go @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package main + +import ( + "azure.logicappsstandard/internal/cmd" + + "github.com/azure/azure-dev/cli/azd/pkg/azdext" +) + +func main() { + azdext.Run(cmd.NewRootCommand()) +} diff --git a/cli/azd/extensions/azure.logicappsstandard/version.txt b/cli/azd/extensions/azure.logicappsstandard/version.txt new file mode 100644 index 00000000000..8acdd82b765 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/version.txt @@ -0,0 +1 @@ +0.0.1 From 252f1a7f4c8451608e20192462d5e72e3f922cdf Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 15:04:41 +0000 Subject: [PATCH 02/38] Fix usage value in extension --- cli/azd/extensions/azure.logicappsstandard/extension.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/extension.yaml b/cli/azd/extensions/azure.logicappsstandard/extension.yaml index 567bae27402..f6663a3210c 100644 --- a/cli/azd/extensions/azure.logicappsstandard/extension.yaml +++ b/cli/azd/extensions/azure.logicappsstandard/extension.yaml @@ -3,7 +3,7 @@ id: azure.logicappsstandard namespace: logicappsstandard displayName: Azure Logic Apps Standard description: Extension for packaging Logic Apps Standard projects, including support for custom code projects -usage: Use 'language: logicappsstandard' in your service configuration to package the service as a Logic Apps Standard project. Use the customCodeProject property to specify a custom code project to include in the package. E.g. 'customCodeProject: Functions/Functions.csproj' +usage: Use logicappsstandard as language in your service configuration. If your Logic App has a custom code project, configure that path to the .csproj file using the customCodeProject property. # NOTE: Make sure version.txt is in sync with this version. version: 0.0.1 language: go From 4a128a814c2a92c9b011ee63cb92d9717d8ff67f Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 15:30:57 +0000 Subject: [PATCH 03/38] Update readme for azure.logicappsstandard extension --- .../azure.logicappsstandard/README.md | 141 +++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/README.md b/cli/azd/extensions/azure.logicappsstandard/README.md index aa8e9a306a2..2f70031789e 100644 --- a/cli/azd/extensions/azure.logicappsstandard/README.md +++ b/cli/azd/extensions/azure.logicappsstandard/README.md @@ -1,3 +1,142 @@ # Azure Logic Apps Standard extension -Azure Developer CLI (azd) extension for packaging Logic Apps Standard projects, including support for custom code projects. +This azd extension makes it possible to package Logic Apps Standard projects and includes support for custom code projects. + + +## Installing + +Assuming 'azd' is in your path, run the following commands to install the extension for the first time: + +```shell +azd extension install azure.logicappsstandard +``` + +Or, if you already the `azure.logicappsstandard` extension installed, and you want to upgrade to the latest version: + +```shell +azd extension upgrade azure.logicappsstandard +``` + +## Usage + +This extension introduces the `logicappsstandard` language wich can package Logic Apps Standard projects. + +For example, if your template has a Logic App Standard project with the following structure: + +``` +└── src + └── logicApp + ├── .vscode + ├── Artifacts + ├── lib + ├── SampleWorkflow1 + │ └── workflow.json + ├── SampleWorkflow2 + │ └── workflow.json + ├── workflow-designtime + ├── .funcignore + ├── .gitignore + ├── host.json + └── local.settings.json +``` + +Use the following snippet in your `azure.yaml` file to configure the Logic App: + +```yaml +services: + logicApp: + project: ./src/logicApp + host: function + language: logicappsstandard +``` + +This will package everything under the `src/logicApp` folder in a .zip file. Because `function` is used as the host, the exclusions in `.funcignore` are respected and only the relevant files are packaged. + +The extension also supports Logic App Standard projects with a .NET 8 or .NET Framework custom code project. For example, if your template has a Logic App Standard project with custom code project following this structure: + +``` +└── src + └── logicApp + ├── Functions + │ ├── MyFunctions.cs + │ ├── Functions.csproj + │ └── ... + └── Workflows + ├── SampleWorkflow1 + │ └── workflow.json + ├── SampleWorkflow1 + │ └── workflow.json + ├── host.json + └── ... +``` + +You can use the following snippet in your `azure.yaml` file to configure the Logic App: + +```yaml +services: + logicAppSample2: + project: ./src/logicApp + dist: Workflows + host: function + language: logicappsstandard + customCodeProject: Functions/Functions.csproj +``` + +This will first build the custom code project and then package the Logic App Standard artifacts. + +- The `project` property contains the rootfolder of the Logic App Standard project. +- The `dist` property is the relative path to the folder with the Logic App Standard files that will be packaged. +- The `customCodeProject` property is the path to the custom code project's `.csproj` file. + + +## Local Development + +### Prerequisites + +1. **Install developer kit extension** (if not already installed): + ```bash + azd ext install microsoft.azd.extensions + ``` + + > **Note**: If you encounter an error about the extension not being in the registry, verify you have the default source configured: + > ```bash + > azd ext source list + > ``` + > If missing, add it: + > ```bash + > azd ext source add -n azd -t url -l "https://aka.ms/azd/extensions/registry" + > ``` + +### Building and Installing + +1. **Navigate to the extension directory**: + ```bash + cd cli/azd/extensions/azure.logicappsstandard + ``` + +2. **Initial setup** (first time only): + ```bash + azd x build + azd x pack + azd x publish + ``` + +3. **Install the extension**: + ```bash + azd ext install azure.logicappsstandard + ``` + +4. **For subsequent development** (after initial setup): + ```bash + azd x watch + ``` + This automatically watches for file changes, rebuilds, and installs updates locally. + + Or for manual builds: + ```bash + azd x build + ``` + This builds and automatically installs the updated extension. + +> [!NOTE] +> The `pack` and `publish` steps are only required for the first time setup. For ongoing development, `azd x watch` or `azd x build` handles all updates automatically. From d35ff9c6b14f84fcbf9b3ca76e32043bee014700 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 15:52:02 +0000 Subject: [PATCH 04/38] Fix README formatting and add troubleshooting section for Logic Apps Standard extension Co-authored-by: Copilot --- .../azure.logicappsstandard/README.md | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/README.md b/cli/azd/extensions/azure.logicappsstandard/README.md index 2f70031789e..3fdef6a16ad 100644 --- a/cli/azd/extensions/azure.logicappsstandard/README.md +++ b/cli/azd/extensions/azure.logicappsstandard/README.md @@ -8,18 +8,18 @@ This azd extension makes it possible to package Logic Apps Standard projects and Assuming 'azd' is in your path, run the following commands to install the extension for the first time: ```shell -azd extension install azure.logicappsstandard +azd ext install azure.logicappsstandard ``` -Or, if you already the `azure.logicappsstandard` extension installed, and you want to upgrade to the latest version: +Or, if you already have the `azure.logicappsstandard` extension installed, and you want to upgrade to the latest version: ```shell -azd extension upgrade azure.logicappsstandard +azd ext upgrade azure.logicappsstandard ``` ## Usage -This extension introduces the `logicappsstandard` language wich can package Logic Apps Standard projects. +This extension introduces the `logicappsstandard` language which can package Logic Apps Standard projects. For example, if your template has a Logic App Standard project with the following structure: @@ -64,7 +64,7 @@ The extension also supports Logic App Standard projects with a .NET 8 or .NET Fr └── Workflows ├── SampleWorkflow1 │ └── workflow.json - ├── SampleWorkflow1 + ├── SampleWorkflow2 │ └── workflow.json ├── host.json └── ... @@ -84,11 +84,24 @@ services: This will first build the custom code project and then package the Logic App Standard artifacts. -- The `project` property contains the rootfolder of the Logic App Standard project. +> [!NOTE] +> When using `customCodeProject`, make sure the required build toolchain is installed: .NET 8 SDK for .NET 8 projects, or .NET Framework/MSBuild tools for .NET Framework projects. + +- The `project` property contains the root folder of the Logic App Standard project. - The `dist` property is the relative path to the folder with the Logic App Standard files that will be packaged. - The `customCodeProject` property is the path to the custom code project's `.csproj` file. +## Troubleshooting + +### Language 'logicappsstandard' is not supported + +If you see the following error while packaging a Logic App Standard project, azd could not find an installed extension that provides the `logicappsstandard` language. Make sure to install the `azure.logicappsstandard` extension. + +``` +ERROR: initializing service '...', getting framework service: language 'logicappsstandard' is not supported by built-in framework services and no extensions are currently providing it +``` + ## Local Development ### Prerequisites From 6d0360e8c37c5442bbb814c2878429262d4accf9 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 15:54:39 +0000 Subject: [PATCH 05/38] Remove version from azure.logicappsstandard root.go Doesn't seem to be used, so this reduces number of places with version --- .../extensions/azure.logicappsstandard/internal/cmd/root.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go index b33ca85d993..60649ca50f7 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go @@ -10,14 +10,12 @@ import ( const ( extensionID = "azure.logicappsstandard" - version = "0.0.1" ) func NewRootCommand() *cobra.Command { rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{ - Name: extensionID, - Version: version, - Short: "Extension for packaging Logic Apps Standard projects, including support for custom code projects", + Name: extensionID, + Short: "Extension for packaging Logic Apps Standard projects, including support for custom code projects", }) // Standard lifecycle, metadata, and version commands From 57efa28ca0948fd2d38945141f6c689d644d132b Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 15:58:58 +0000 Subject: [PATCH 06/38] Update change log for azure.logicappsstandard --- cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md index b88d613cce0..670d489a856 100644 --- a/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md +++ b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md @@ -1,3 +1,5 @@ # Release History -## 0.0.1 - Initial Version \ No newline at end of file +## 0.0.1 + +- Initial release with support for packaging Logic App Standard projects via `language: logicappsstandard` in `azure.yaml`, and optional custom code projects using `customCodeProject` poperty. \ No newline at end of file From 978621c444713cad2148d4368819400a7b76c818 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 16:01:17 +0000 Subject: [PATCH 07/38] Add workflow to lint azure.logicappsstandard extension --- .../lint-ext-azure-logicappsstandard.yml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/lint-ext-azure-logicappsstandard.yml diff --git a/.github/workflows/lint-ext-azure-logicappsstandard.yml b/.github/workflows/lint-ext-azure-logicappsstandard.yml new file mode 100644 index 00000000000..57f8dd4dabb --- /dev/null +++ b/.github/workflows/lint-ext-azure-logicappsstandard.yml @@ -0,0 +1,22 @@ +name: ext-azure-logicappsstandard-ci + +on: + pull_request: + paths: + - "cli/azd/extensions/azure.logicappsstandard/**" + - ".github/workflows/lint-ext-azure-logicappsstandard.yml" + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + +jobs: + lint: + uses: ./.github/workflows/lint-go.yml + with: + working-directory: cli/azd/extensions/azure.logicappsstandard From 1cede8fbd73467c3ebaea4b02320557c4dca71aa Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 16:04:04 +0000 Subject: [PATCH 08/38] Add release pipeline for azure.logicappsstandard extension --- .../release-ext-azure-logicappsstandard.yml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 eng/pipelines/release-ext-azure-logicappsstandard.yml diff --git a/eng/pipelines/release-ext-azure-logicappsstandard.yml b/eng/pipelines/release-ext-azure-logicappsstandard.yml new file mode 100644 index 00000000000..7987664d997 --- /dev/null +++ b/eng/pipelines/release-ext-azure-logicappsstandard.yml @@ -0,0 +1,33 @@ +# Continuous deployment trigger +trigger: + branches: + include: + - main + paths: + include: + - go.mod + - cli/azd/extensions/azure.logicappsstandard + - eng/pipelines/release-azd-extension.yml + - /eng/pipelines/templates/jobs/build-azd-extension.yml + - /eng/pipelines/templates/jobs/cross-build-azd-extension.yml + - /eng/pipelines/templates/variables/image.yml + +pr: + paths: + include: + - cli/azd/extensions/azure.logicappsstandard + - eng/pipelines/release-ext-azure-logicappsstandard.yml + - eng/pipelines/release-azd-extension.yml + - eng/pipelines/templates/steps/publish-cli.yml + exclude: + - cli/azd/docs/** + +extends: + template: /eng/pipelines/templates/stages/1es-redirect.yml + parameters: + stages: + - template: /eng/pipelines/templates/stages/release-azd-extension.yml + parameters: + AzdExtensionId: azure.logicappsstandard + SanitizedExtensionId: azure-logicappsstandard + AzdExtensionDirectory: cli/azd/extensions/azure.logicappsstandard From 75df09c498d6578cfafc3cbdb4c17d4bccf26847 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 16:34:15 +0000 Subject: [PATCH 09/38] Revert "Remove version from azure.logicappsstandard root.go" This reverts commit 9675a81d5bae8445bda729a1c652e99dbb300eb3. --- .../extensions/azure.logicappsstandard/internal/cmd/root.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go index 60649ca50f7..b33ca85d993 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go @@ -10,12 +10,14 @@ import ( const ( extensionID = "azure.logicappsstandard" + version = "0.0.1" ) func NewRootCommand() *cobra.Command { rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{ - Name: extensionID, - Short: "Extension for packaging Logic Apps Standard projects, including support for custom code projects", + Name: extensionID, + Version: version, + Short: "Extension for packaging Logic Apps Standard projects, including support for custom code projects", }) // Standard lifecycle, metadata, and version commands From 1818f47d56a15005cbc23b9e37408a23726c0b38 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 16:37:30 +0000 Subject: [PATCH 10/38] Use t.Context() instead of context.Background() in logicappsstandard extension for consistency --- ...ramework_service_logicappsstandard_test.go | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index 01cb03a6149..130bd5074bc 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -4,7 +4,6 @@ package project import ( - "context" "os" "path/filepath" "strings" @@ -47,13 +46,13 @@ func TestRequiredExternalTools(t *testing.T) { provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} t.Run("returns nil when custom code is not configured", func(t *testing.T) { - tools, err := provider.RequiredExternalTools(context.Background(), newServiceConfig("logicApp", "src/logicApp", nil)) + tools, err := provider.RequiredExternalTools(t.Context(), newServiceConfig("logicApp", "src/logicApp", nil)) require.NoError(t, err) assert.Nil(t, tools) }) t.Run("returns dotnet when custom code is configured", func(t *testing.T) { - tools, err := provider.RequiredExternalTools(context.Background(), newServiceConfig("logicApp", "src/logicApp", map[string]any{ + tools, err := provider.RequiredExternalTools(t.Context(), newServiceConfig("logicApp", "src/logicApp", map[string]any{ "customCodeProject": "Functions/Functions.csproj", })) require.NoError(t, err) @@ -104,7 +103,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", nil) - err := provider.Initialize(context.Background(), svc) + err := provider.Initialize(t.Context(), svc) require.NoError(t, err) assert.Equal(t, svc, provider.serviceConfig) }) @@ -118,7 +117,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { createFile(t, filepath.Join(projectDir, "src/logicApp/Functions/Functions.csproj"), "\n") withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { - err := provider.Initialize(context.Background(), svc) + err := provider.Initialize(t.Context(), svc) require.NoError(t, err) }) }) @@ -133,7 +132,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { require.NoError(t, err) withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { - err := provider.Initialize(context.Background(), svc) + err := provider.Initialize(t.Context(), svc) require.Error(t, err) assert.Contains(t, err.Error(), "must point to a file") }) @@ -146,7 +145,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { }) withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { - err := provider.Initialize(context.Background(), svc) + err := provider.Initialize(t.Context(), svc) require.Error(t, err) assert.Contains(t, err.Error(), "custom code project not found") }) @@ -159,7 +158,7 @@ func TestPackageUsesProjectAndOutputPaths(t *testing.T) { createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { - result, err := provider.Package(context.Background(), newServiceConfig("logicApp", "src/logicApp", nil), nil, func(string) {}) + result, err := provider.Package(t.Context(), newServiceConfig("logicApp", "src/logicApp", nil), nil, func(string) {}) require.NoError(t, err) require.Len(t, result.Artifacts, 1) @@ -174,7 +173,7 @@ func TestPackageUsesProjectAndOutputPaths(t *testing.T) { svc := newServiceConfig("logicApp", "src/logicApp", nil) svc.OutputPath = "Workflows" - result, err := provider.Package(context.Background(), svc, nil, func(string) {}) + result, err := provider.Package(t.Context(), svc, nil, func(string) {}) require.NoError(t, err) expectedPath := filepath.Join(projectDir, "src/logicApp", "Workflows") require.NotEmpty(t, result.Artifacts) @@ -203,9 +202,9 @@ func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { withEnv(t, "DOTNET_ARGS_LOG", logFile, func() { withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() { - _, err := provider.Restore(context.Background(), svc, nil, func(string) {}) + _, err := provider.Restore(t.Context(), svc, nil, func(string) {}) require.NoError(t, err) - _, err = provider.Build(context.Background(), svc, nil, func(string) {}) + _, err = provider.Build(t.Context(), svc, nil, func(string) {}) require.NoError(t, err) }) }) @@ -236,9 +235,9 @@ func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) { withEnv(t, "DOTNET_ARGS_LOG", logFile, func() { withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() { - _, err := provider.Restore(context.Background(), svc, nil, func(string) {}) + _, err := provider.Restore(t.Context(), svc, nil, func(string) {}) require.NoError(t, err) - _, err = provider.Build(context.Background(), svc, nil, func(string) {}) + _, err = provider.Build(t.Context(), svc, nil, func(string) {}) require.NoError(t, err) }) }) From 7ca22d70906af669cd02a55021a17aaa47056e9f Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 16:39:10 +0000 Subject: [PATCH 11/38] Cleanup dependencies for azure.logicappsstandard extension --- cli/azd/extensions/azure.logicappsstandard/go.mod | 11 +++++------ cli/azd/extensions/azure.logicappsstandard/go.sum | 2 -- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/go.mod b/cli/azd/extensions/azure.logicappsstandard/go.mod index 490ccd867a9..24c7d99c965 100644 --- a/cli/azd/extensions/azure.logicappsstandard/go.mod +++ b/cli/azd/extensions/azure.logicappsstandard/go.mod @@ -3,16 +3,16 @@ module azure.logicappsstandard go 1.26.1 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 github.com/azure/azure-dev/cli/azd v1.24.2 - github.com/fatih/color v1.19.0 github.com/spf13/cobra v1.10.2 + github.com/stretchr/testify v1.11.1 + google.golang.org/protobuf v1.36.11 ) require ( github.com/AlecAivazis/survey/v2 v2.3.7 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 // indirect @@ -43,6 +43,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dlclark/regexp2 v1.12.0 // indirect github.com/drone/envsubst v1.0.3 // indirect + github.com/fatih/color v1.19.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gofrs/flock v0.13.0 // indirect @@ -77,7 +78,6 @@ require ( github.com/sethvargo/go-retry v0.3.0 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/stretchr/testify v1.11.1 // indirect github.com/theckman/yacspin v0.13.12 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect @@ -100,6 +100,5 @@ require ( golang.org/x/time v0.15.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 // indirect google.golang.org/grpc v1.80.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/cli/azd/extensions/azure.logicappsstandard/go.sum b/cli/azd/extensions/azure.logicappsstandard/go.sum index 4735d1e22a8..a5786473fe8 100644 --- a/cli/azd/extensions/azure.logicappsstandard/go.sum +++ b/cli/azd/extensions/azure.logicappsstandard/go.sum @@ -15,8 +15,6 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0 h1:2qsI github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0/go.mod h1:AW8VEadnhw9xox+VaVd9sP7NjzOAnaZBLRH6Tq3cJ38= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0 h1:nnQ9vXH039UrEFxi08pPuZBE7VfqSJt343uJLw0rhWI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0/go.mod h1:4YIVtzMFVsPwBvitCDX7J9sqthSj43QD1sP6fYc1egc= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 h1:wxQx2Bt4xzPIKvW59WQf1tJNx/ZZKPfN+EhPX3Z6CYY= From b0079199079070185f50a8c0a28189f537e20878 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 16:47:16 +0000 Subject: [PATCH 12/38] Fix typo in azure.logicappsstandard changelog --- cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md index 670d489a856..f942c9989b3 100644 --- a/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md +++ b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md @@ -2,4 +2,4 @@ ## 0.0.1 -- Initial release with support for packaging Logic App Standard projects via `language: logicappsstandard` in `azure.yaml`, and optional custom code projects using `customCodeProject` poperty. \ No newline at end of file +- Initial release with support for packaging Logic App Standard projects via `language: logicappsstandard` in `azure.yaml`, and optional custom code projects using `customCodeProject` property. \ No newline at end of file From 13d9953570f6c45a9c133d948ee5083a1e22f9b9 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:28:47 +0200 Subject: [PATCH 13/38] Update cli/azd/extensions/azure.logicappsstandard/main.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cli/azd/extensions/azure.logicappsstandard/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/main.go b/cli/azd/extensions/azure.logicappsstandard/main.go index 0f77478c02b..32b4f714487 100644 --- a/cli/azd/extensions/azure.logicappsstandard/main.go +++ b/cli/azd/extensions/azure.logicappsstandard/main.go @@ -4,9 +4,9 @@ package main import ( - "azure.logicappsstandard/internal/cmd" - "github.com/azure/azure-dev/cli/azd/pkg/azdext" + + "azure.logicappsstandard/internal/cmd" ) func main() { From 2f0a19d09ff9347ed600d8437d1decf9847f823c Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 16:54:08 +0000 Subject: [PATCH 14/38] Remove 'packaging' from LogicAppsStandardFrameworkServiceProvider name --- .../internal/cmd/listen.go | 2 +- .../framework_service_logicappsstandard.go | 28 +++++++++---------- ...ramework_service_logicappsstandard_test.go | 22 +++++++-------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go index 238b2322223..c48cc804efe 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go @@ -12,6 +12,6 @@ import ( // configureListen is called by NewListenCommand to register event handlers. func configureListen(host *azdext.ExtensionHost) { host.WithFrameworkService("logicappsstandard", func() azdext.FrameworkServiceProvider { - return project.NewLogicAppsStandardPackagingFrameworkServiceProvider() + return project.NewLogicAppsStandardFrameworkServiceProvider() }) } diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index adabb63fb3f..1137e23e2f8 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -12,21 +12,21 @@ import ( "github.com/azure/azure-dev/cli/azd/pkg/azdext" ) -// Ensure LogicAppsStandardPackagingFrameworkServiceProvider implements FrameworkServiceProvider interface -var _ azdext.FrameworkServiceProvider = &LogicAppsStandardPackagingFrameworkServiceProvider{} +// Ensure LogicAppsStandardFrameworkServiceProvider implements FrameworkServiceProvider interface +var _ azdext.FrameworkServiceProvider = &LogicAppsStandardFrameworkServiceProvider{} -// LogicAppsStandardPackagingFrameworkServiceProvider introduces the custom language 'logicappsstandard' to the framework service provider, -// enabling it to handle packaging for Logic Apps Standard projects, including those with custom code components. -type LogicAppsStandardPackagingFrameworkServiceProvider struct { +// LogicAppsStandardFrameworkServiceProvider introduces the custom language 'logicappsstandard', +// which makes it possible to package Logic Apps Standard projects, including those with custom code components. +type LogicAppsStandardFrameworkServiceProvider struct { serviceConfig *azdext.ServiceConfig } -func NewLogicAppsStandardPackagingFrameworkServiceProvider() azdext.FrameworkServiceProvider { - return &LogicAppsStandardPackagingFrameworkServiceProvider{} +func NewLogicAppsStandardFrameworkServiceProvider() azdext.FrameworkServiceProvider { + return &LogicAppsStandardFrameworkServiceProvider{} } // Initialize initializes the framework service provider with service configuration -func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Initialize(ctx context.Context, serviceConfig *azdext.ServiceConfig) error { +func (p *LogicAppsStandardFrameworkServiceProvider) Initialize(ctx context.Context, serviceConfig *azdext.ServiceConfig) error { fmt.Printf("Initializing Logic Apps Standard framework for service: %s\n", serviceConfig.GetName()) p.serviceConfig = serviceConfig @@ -48,7 +48,7 @@ func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Initialize(ctx cont } // Returns dotnet as required external tool if a custom code project is configured -func (p *LogicAppsStandardPackagingFrameworkServiceProvider) RequiredExternalTools( +func (p *LogicAppsStandardFrameworkServiceProvider) RequiredExternalTools( ctx context.Context, serviceConfig *azdext.ServiceConfig, ) ([]*azdext.ExternalTool, error) { @@ -64,7 +64,7 @@ func (p *LogicAppsStandardPackagingFrameworkServiceProvider) RequiredExternalToo } // Requirements returns the framework requirements (whether restore/build are needed) -func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Requirements() (*azdext.FrameworkRequirements, error) { +func (p *LogicAppsStandardFrameworkServiceProvider) Requirements() (*azdext.FrameworkRequirements, error) { hasCustomCodeProject := p.serviceConfig != nil && hasCustomCodeProjectConfigured(p.serviceConfig) return &azdext.FrameworkRequirements{ Package: &azdext.FrameworkPackageRequirements{ @@ -75,7 +75,7 @@ func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Requirements() (*az } // Restores the dependencies for the custom code project if specified in the service configuration. -func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Restore( +func (p *LogicAppsStandardFrameworkServiceProvider) Restore( ctx context.Context, serviceConfig *azdext.ServiceConfig, serviceContext *azdext.ServiceContext, @@ -95,7 +95,7 @@ func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Restore( } // Builds the custom code project if specified in the service configuration. -func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Build( +func (p *LogicAppsStandardFrameworkServiceProvider) Build( ctx context.Context, serviceConfig *azdext.ServiceConfig, serviceContext *azdext.ServiceContext, @@ -115,7 +115,7 @@ func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Build( } // Packages the Logic Apps Standard project, including any custom code components, into a deployable artifact. -func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Package( +func (p *LogicAppsStandardFrameworkServiceProvider) Package( ctx context.Context, serviceConfig *azdext.ServiceConfig, serviceContext *azdext.ServiceContext, @@ -152,7 +152,7 @@ func (p *LogicAppsStandardPackagingFrameworkServiceProvider) Package( }, nil } -func (p *LogicAppsStandardPackagingFrameworkServiceProvider) resolveCustomCodeProjectPath( +func (p *LogicAppsStandardFrameworkServiceProvider) resolveCustomCodeProjectPath( serviceConfig *azdext.ServiceConfig, ) (string, error) { projectDir, err := azdext.GetProjectDir() diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index 130bd5074bc..55df8c7aae1 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -43,7 +43,7 @@ func TestHasCustomCodeProjectConfigured(t *testing.T) { } func TestRequiredExternalTools(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} t.Run("returns nil when custom code is not configured", func(t *testing.T) { tools, err := provider.RequiredExternalTools(t.Context(), newServiceConfig("logicApp", "src/logicApp", nil)) @@ -64,7 +64,7 @@ func TestRequiredExternalTools(t *testing.T) { func TestRequirements(t *testing.T) { t.Run("disables restore and build when service config is not initialized", func(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} reqs, err := provider.Requirements() require.NoError(t, err) require.NotNil(t, reqs.Package) @@ -73,7 +73,7 @@ func TestRequirements(t *testing.T) { }) t.Run("disables restore and build when initialized without customCodeProject", func(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} provider.serviceConfig = newServiceConfig("logicApp", "src/logicApp", nil) reqs, err := provider.Requirements() require.NoError(t, err) @@ -83,7 +83,7 @@ func TestRequirements(t *testing.T) { }) t.Run("enables restore and build when customCodeProject is configured", func(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} provider.serviceConfig = newServiceConfig("logicApp", "src/logicApp", map[string]any{ "customCodeProject": "Functions/Functions.csproj", }) @@ -100,7 +100,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") t.Run("succeeds without customCodeProject and sets serviceConfig", func(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", nil) err := provider.Initialize(t.Context(), svc) @@ -109,7 +109,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { }) t.Run("succeeds when custom code project file exists", func(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ "customCodeProject": "Functions/Functions.csproj", }) @@ -123,7 +123,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { }) t.Run("fails when custom code project is a directory", func(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ "customCodeProject": "Functions", }) @@ -139,7 +139,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { }) t.Run("fails when custom code project file is missing", func(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ "customCodeProject": "Functions/Missing.csproj", }) @@ -153,7 +153,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { } func TestPackageUsesProjectAndOutputPaths(t *testing.T) { - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} projectDir := t.TempDir() createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") @@ -197,7 +197,7 @@ func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ "customCodeProject": "Functions/Functions.csproj", }) - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { withEnv(t, "DOTNET_ARGS_LOG", logFile, func() { @@ -230,7 +230,7 @@ func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) { err := os.Chmod(fakeDotnetPath, 0o755) require.NoError(t, err) - provider := &LogicAppsStandardPackagingFrameworkServiceProvider{} + provider := &LogicAppsStandardFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", nil) withEnv(t, "DOTNET_ARGS_LOG", logFile, func() { From ec0db87353ae3c4dbc554aa79119baee6f750780 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:00:21 +0000 Subject: [PATCH 15/38] Fix linting issues --- .../framework_service_logicappsstandard.go | 5 ++++- .../framework_service_logicappsstandard_test.go | 15 ++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index 1137e23e2f8..51c73099d29 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -26,7 +26,10 @@ func NewLogicAppsStandardFrameworkServiceProvider() azdext.FrameworkServiceProvi } // Initialize initializes the framework service provider with service configuration -func (p *LogicAppsStandardFrameworkServiceProvider) Initialize(ctx context.Context, serviceConfig *azdext.ServiceConfig) error { +func (p *LogicAppsStandardFrameworkServiceProvider) Initialize( + ctx context.Context, + serviceConfig *azdext.ServiceConfig, +) error { fmt.Printf("Initializing Logic Apps Standard framework for service: %s\n", serviceConfig.GetName()) p.serviceConfig = serviceConfig diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index 55df8c7aae1..2148ec2b85f 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -52,9 +52,11 @@ func TestRequiredExternalTools(t *testing.T) { }) t.Run("returns dotnet when custom code is configured", func(t *testing.T) { - tools, err := provider.RequiredExternalTools(t.Context(), newServiceConfig("logicApp", "src/logicApp", map[string]any{ - "customCodeProject": "Functions/Functions.csproj", - })) + tools, err := provider.RequiredExternalTools( + t.Context(), + newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + })) require.NoError(t, err) require.Len(t, tools, 1) assert.Equal(t, "dotnet", tools[0].Name) @@ -245,7 +247,10 @@ func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) { if _, statErr := os.Stat(logFile); statErr == nil { contents, readErr := os.ReadFile(logFile) require.NoError(t, readErr) - assert.Empty(t, strings.TrimSpace(string(contents)), "dotnet should not be invoked when customCodeProject is not configured") + assert.Empty( + t, + strings.TrimSpace(string(contents)), + "dotnet should not be invoked when customCodeProject is not configured") } else { require.ErrorIs(t, statErr, os.ErrNotExist) } @@ -288,6 +293,6 @@ func createFile(t *testing.T, filePath, content string) { t.Helper() err := os.MkdirAll(filepath.Dir(filePath), 0o755) require.NoError(t, err, "failed creating directory %q", filepath.Dir(filePath)) - err = os.WriteFile(filePath, []byte(content), 0o644) + err = os.WriteFile(filePath, []byte(content), 0o600) require.NoError(t, err, "failed writing file %q", filePath) } From 00a128f1787ef76e3b096cbbecdfe9ef516d001a Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:09:35 +0000 Subject: [PATCH 16/38] Refactor test setup by introducing createFakeDotnetStub for cross-platform compatibility Co-authored-by: Copilot --- ...ramework_service_logicappsstandard_test.go | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index 2148ec2b85f..fdfc2ac8fc2 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -6,6 +6,7 @@ package project import ( "os" "path/filepath" + "runtime" "strings" "testing" @@ -191,10 +192,7 @@ func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { logFile := filepath.Join(t.TempDir(), "dotnet.log") fakeBinDir := t.TempDir() - fakeDotnetPath := filepath.Join(fakeBinDir, "dotnet") - createFile(t, fakeDotnetPath, "#!/bin/sh\nprintf '%s\n' \"$*\" >> \"$DOTNET_ARGS_LOG\"\n") - err := os.Chmod(fakeDotnetPath, 0o755) - require.NoError(t, err) + createFakeDotnetStub(t, fakeBinDir) svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ "customCodeProject": "Functions/Functions.csproj", @@ -214,7 +212,8 @@ func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { contents, err := os.ReadFile(logFile) require.NoError(t, err) - logLines := strings.Split(strings.TrimSpace(string(contents)), "\n") + normalized := strings.ReplaceAll(string(contents), "\r\n", "\n") + logLines := strings.Split(strings.TrimSpace(normalized), "\n") require.Len(t, logLines, 2, "expected two dotnet invocations: %q", string(contents)) expectedRestore := "restore " + csprojPath @@ -227,10 +226,7 @@ func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) { logFile := filepath.Join(t.TempDir(), "dotnet.log") fakeBinDir := t.TempDir() - fakeDotnetPath := filepath.Join(fakeBinDir, "dotnet") - createFile(t, fakeDotnetPath, "#!/bin/sh\nprintf '%s\n' \"$*\" >> \"$DOTNET_ARGS_LOG\"\n") - err := os.Chmod(fakeDotnetPath, 0o755) - require.NoError(t, err) + createFakeDotnetStub(t, fakeBinDir) provider := &LogicAppsStandardFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", nil) @@ -289,6 +285,25 @@ func withEnv(t *testing.T, key, value string, fn func()) { fn() } +// createFakeDotnetStub places a fake dotnet executable in fakeBinDir. +// On Windows it creates dotnet.cmd (a batch file) so that cmd.exe can find +// and execute it via PATHEXT; on Unix it creates a dotnet shell script. +// Both stubs append their arguments to the file named by DOTNET_ARGS_LOG. +func createFakeDotnetStub(t *testing.T, fakeBinDir string) { + t.Helper() + stubName := "dotnet" + stubContent := "#!/bin/sh\nprintf '%s\n' \"$*\" >> \"$DOTNET_ARGS_LOG\"\n" + stubMode := os.FileMode(0o755) + if runtime.GOOS == "windows" { + stubName = "dotnet.cmd" + stubContent = "@echo off\r\necho %* >> %DOTNET_ARGS_LOG%\r\n" + stubMode = 0o644 + } + stubPath := filepath.Join(fakeBinDir, stubName) + err := os.WriteFile(stubPath, []byte(stubContent), stubMode) + require.NoError(t, err, "failed writing fake dotnet stub %q", stubPath) +} + func createFile(t *testing.T, filePath, content string) { t.Helper() err := os.MkdirAll(filepath.Dir(filePath), 0o755) From 60a2e6e547a505789c48fc5509bc11c3cf16a3a5 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:16:02 +0000 Subject: [PATCH 17/38] Clarify comment on packaging to specify host-specific ignore file usage --- .../internal/project/framework_service_logicappsstandard.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index 51c73099d29..25f468117eb 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -143,7 +143,7 @@ func (p *LogicAppsStandardFrameworkServiceProvider) Package( // Return a DIRECTORY artifact pointing to the project root. // azd's packaging pipeline will handle creating the zip archive from this directory. - // By specifying an absolute path, azd will use the .funcignore file to exclude unnecessary files from the package. + // By specifying an absolute path, azd will use the host specific ignore file (e.g. .funcignore) for exclusions. return &azdext.ServicePackageResult{ Artifacts: []*azdext.Artifact{ { From b7e7f6891fa60e53679ed416a9c65ab06ceebb35 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:27:33 +0000 Subject: [PATCH 18/38] Remove use of fmt.Printf from LogicAppsStandardFrameworkServiceProvider Initialize method Co-authored-by: Copilot --- .../internal/project/framework_service_logicappsstandard.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index 25f468117eb..3a45313d061 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -30,7 +30,6 @@ func (p *LogicAppsStandardFrameworkServiceProvider) Initialize( ctx context.Context, serviceConfig *azdext.ServiceConfig, ) error { - fmt.Printf("Initializing Logic Apps Standard framework for service: %s\n", serviceConfig.GetName()) p.serviceConfig = serviceConfig if hasCustomCodeProjectConfigured(serviceConfig) { From 66e5baa3e33978818ae4b6ee006afc93cd4f6ea9 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:34:10 +0000 Subject: [PATCH 19/38] Add CI scripts --- .../azure.logicappsstandard/ci-build.ps1 | 150 ++++++++++++++++++ .../azure.logicappsstandard/ci-test.ps1 | 27 ++++ 2 files changed, 177 insertions(+) create mode 100644 cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 create mode 100644 cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 diff --git a/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 new file mode 100644 index 00000000000..4d429781493 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 @@ -0,0 +1,150 @@ +param( + [string] $Version = (Get-Content "$PSScriptRoot/version.txt"), + [string] $SourceVersion = (git rev-parse HEAD), + [switch] $CodeCoverageEnabled, + [switch] $BuildRecordMode, + [string] $MSYS2Shell, # path to msys2_shell.cmd + [string] $OutputFileName +) +$PSNativeCommandArgumentPassing = 'Legacy' + +# Remove any previously built binaries +go clean + +if ($LASTEXITCODE) { + Write-Host "Error running go clean" + exit $LASTEXITCODE +} + +# Run `go help build` to obtain detailed information about `go build` flags. +$buildFlags = @( + # remove all file system paths from the resulting executable. + # Instead of absolute file system paths, the recorded file names + # will begin either a module path@version (when using modules), + # or a plain import path (when using the standard library, or GOPATH). + "-trimpath", + + # Use buildmode=pie (Position Independent Executable) for enhanced security across platforms + # against memory corruption exploits across all major platforms. + # + # On Windows, the -buildmode=pie flag enables Address Space Layout + # Randomization (ASLR) and automatically sets DYNAMICBASE and HIGH-ENTROPY-VA flags in the PE header. + "-buildmode=pie" +) + +if ($CodeCoverageEnabled) { + $buildFlags += "-cover" +} + +# Build constraint tags +# cfi: Enable Control Flow Integrity (CFI), +# cfg: Enable Control Flow Guard (CFG), +# osusergo: Optimize for OS user accounts +$tagsFlag = "-tags=cfi,cfg,osusergo" + +# ld linker flags +# -s: Omit symbol table and debug information +# -w: Omit DWARF symbol table +# -X: Set variable at link time. Used to set the version in source. + +$ldFlag = "-ldflags=-s -w -X 'logicappsstandard/internal/version.Version=$Version'" + +if ($IsWindows) { + $msg = "Building for Windows" + Write-Host $msg +} +elseif ($IsLinux) { + Write-Host "Building for linux" + + # Disable cgo in the x64 Linux build. This will also statically + # link the resulting binary which increases backwards + # compatibility with older versions of Linux. + if ($env:GOARCH -ne "arm64") { + $env:CGO_ENABLED = "0" + } +} +elseif ($IsMacOS) { + Write-Host "Building for macOS" +} + +# Add output file flag based on specified output file name +$outputFlag = "-o=$OutputFileName" + +# collect flags +$buildFlags += @( + $tagsFlag, + $ldFlag, + $outputFlag +) + +function PrintFlags() { + param( + [string] $flags + ) + + # Attempt to format flags so that they are easily copy-pastable to be ran inside pwsh + $i = 0 + foreach ($buildFlag in $buildFlags) { + # If the flag has a value, wrap it in quotes. This is not required when invoking directly below, + # but when repasted into a shell for execution, the quotes can help escape special characters such as ','. + $argWithValue = $buildFlag.Split('=', 2) + if ($argWithValue.Length -eq 2 -and !$argWithValue[1].StartsWith("`"")) { + $buildFlag = "$($argWithValue[0])=`"$($argWithValue[1])`"" + } + + # Write each flag on a newline with '`' acting as the multiline separator + if ($i -eq $buildFlags.Length - 1) { + Write-Host " $buildFlag" + } + else { + Write-Host " $buildFlag ``" + } + $i++ + } +} + +$oldGOEXPERIMENT = $env:GOEXPERIMENT +# Enable the loopvar experiment, which makes the loop variable for go loops like `range` behave as most folks would expect. +# the go team is exploring making this default in the future, and we'd like to opt into the behavior now. +$env:GOEXPERIMENT = "loopvar" + +try { + Write-Host "Running: go build ``" + PrintFlags -flags $buildFlags + go build @buildFlags + if ($LASTEXITCODE) { + Write-Host "Error running go build" + exit $LASTEXITCODE + } + + if ($BuildRecordMode) { + # Modify build tags to include record + $recordTagPatched = $false + for ($i = 0; $i -lt $buildFlags.Length; $i++) { + if ($buildFlags[$i].StartsWith("-tags=")) { + $buildFlags[$i] += ",record" + $recordTagPatched = $true + } + } + if (-not $recordTagPatched) { + $buildFlags += "-tags=record" + } + # Add output file flag for record mode + $recordOutput = "-o=$OutputFileName-record" + if ($IsWindows) { $recordOutput += ".exe" } + $buildFlags += $recordOutput + + Write-Host "Running: go build (record) ``" + PrintFlags -flags $buildFlags + go build @buildFlags + if ($LASTEXITCODE) { + Write-Host "Error running go build (record)" + exit $LASTEXITCODE + } + } + + Write-Host "go build succeeded" +} +finally { + $env:GOEXPERIMENT = $oldGOEXPERIMENT +} \ No newline at end of file diff --git a/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 b/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 new file mode 100644 index 00000000000..2e66dea3138 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 @@ -0,0 +1,27 @@ +$gopath = go env GOPATH +$gotestsumBinary = "gotestsum" +if ($IsWindows) { + $gotestsumBinary += ".exe" +} +$gotestsum = Join-Path $gopath "bin" $gotestsumBinary + +Write-Host "Running unit tests..." + +if (Test-Path $gotestsum) { + # Use gotestsum for better output formatting and summary + & $gotestsum --format testname -- ./... -count=1 +} else { + # Fallback to go test if gotestsum is not installed + Write-Host "gotestsum not found, using go test..." -ForegroundColor Yellow + go test ./... -v -count=1 +} + +if ($LASTEXITCODE -ne 0) { + Write-Host "" + Write-Host "Tests failed with exit code: $LASTEXITCODE" -ForegroundColor Red + exit $LASTEXITCODE +} + +Write-Host "" +Write-Host "All tests passed!" -ForegroundColor Green +exit 0 From 0750e8ef5fc72cd162d0ab93814c1b8d972f7419 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:37:19 +0000 Subject: [PATCH 20/38] Add golangci-lint config file for azure.logicappsstandard --- .../azure.logicappsstandard/.golangci.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 cli/azd/extensions/azure.logicappsstandard/.golangci.yaml diff --git a/cli/azd/extensions/azure.logicappsstandard/.golangci.yaml b/cli/azd/extensions/azure.logicappsstandard/.golangci.yaml new file mode 100644 index 00000000000..b88a74c6a0b --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/.golangci.yaml @@ -0,0 +1,17 @@ +version: "2" + +linters: + default: none + enable: + - gosec + - lll + - unused + - errorlint + settings: + lll: + line-length: 220 + tab-width: 4 + +formatters: + enable: + - gofmt From 84e7d70724affdb543268df0155c3aaa6f1148b2 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:37:39 +0000 Subject: [PATCH 21/38] Fix and suppress linting rules for tests in azure.logicappsstandard Co-authored-by: Copilot --- .../project/framework_service_logicappsstandard_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index fdfc2ac8fc2..a18b90414b4 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -131,7 +131,7 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { "customCodeProject": "Functions", }) - err := os.MkdirAll(filepath.Join(projectDir, "src/logicApp/Functions"), 0o755) + err := os.MkdirAll(filepath.Join(projectDir, "src/logicApp/Functions"), 0o750) require.NoError(t, err) withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { @@ -210,6 +210,7 @@ func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { }) }) + // #nosec G304 -- logFile points to a test-controlled file under t.TempDir(). contents, err := os.ReadFile(logFile) require.NoError(t, err) normalized := strings.ReplaceAll(string(contents), "\r\n", "\n") @@ -241,6 +242,7 @@ func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) { }) if _, statErr := os.Stat(logFile); statErr == nil { + // #nosec G304 -- logFile points to a test-controlled file under t.TempDir(). contents, readErr := os.ReadFile(logFile) require.NoError(t, readErr) assert.Empty( @@ -306,7 +308,7 @@ func createFakeDotnetStub(t *testing.T, fakeBinDir string) { func createFile(t *testing.T, filePath, content string) { t.Helper() - err := os.MkdirAll(filepath.Dir(filePath), 0o755) + err := os.MkdirAll(filepath.Dir(filePath), 0o750) require.NoError(t, err, "failed creating directory %q", filepath.Dir(filePath)) err = os.WriteFile(filePath, []byte(content), 0o600) require.NoError(t, err, "failed writing file %q", filePath) From ba0dd99a332d60fa82c3c07828de5ab58bff6fc5 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:44:50 +0000 Subject: [PATCH 22/38] Introduce version.go file for azure.logicappsstandard the build scripts use -X ldflags to inject version info at build time. Go's -X flag can only set package-level var declarations, not constants - so the ldflags are silently ignored. Commit and BuildDate (also in the ldflags) aren't declared anywhere either. --- .../azure.logicappsstandard/internal/cmd/root.go | 7 ++++--- .../internal/version/version.go | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 cli/azd/extensions/azure.logicappsstandard/internal/version/version.go diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go index b33ca85d993..eddd9c37a59 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go @@ -6,24 +6,25 @@ package cmd import ( "github.com/azure/azure-dev/cli/azd/pkg/azdext" "github.com/spf13/cobra" + + "azure.logicappsstandard/internal/version" ) const ( extensionID = "azure.logicappsstandard" - version = "0.0.1" ) func NewRootCommand() *cobra.Command { rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{ Name: extensionID, - Version: version, + Version: version.Version, Short: "Extension for packaging Logic Apps Standard projects, including support for custom code projects", }) // Standard lifecycle, metadata, and version commands rootCmd.AddCommand(azdext.NewListenCommand(configureListen)) rootCmd.AddCommand(azdext.NewMetadataCommand("1.0", extensionID, NewRootCommand)) - rootCmd.AddCommand(azdext.NewVersionCommand(extensionID, version, &extCtx.OutputFormat)) + rootCmd.AddCommand(azdext.NewVersionCommand(extensionID, version.Version, &extCtx.OutputFormat)) return rootCmd } diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/version/version.go b/cli/azd/extensions/azure.logicappsstandard/internal/version/version.go new file mode 100644 index 00000000000..52188c90118 --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/internal/version/version.go @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package version + +var ( + // Populated at build time + Version = "dev" // Default value for development builds + Commit = "none" + BuildDate = "unknown" +) From eceb96646d7557f8801c4b457bb39c16b69e54f2 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:46:25 +0000 Subject: [PATCH 23/38] Update ci scripts for logicappsstandard based on ai.finetune extension --- .../extensions/azure.logicappsstandard/ci-build.ps1 | 10 +--------- cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 index 4d429781493..f419b648e14 100644 --- a/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 +++ b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 @@ -6,7 +6,6 @@ param( [string] $MSYS2Shell, # path to msys2_shell.cmd [string] $OutputFileName ) -$PSNativeCommandArgumentPassing = 'Legacy' # Remove any previously built binaries go clean @@ -47,7 +46,7 @@ $tagsFlag = "-tags=cfi,cfg,osusergo" # -w: Omit DWARF symbol table # -X: Set variable at link time. Used to set the version in source. -$ldFlag = "-ldflags=-s -w -X 'logicappsstandard/internal/version.Version=$Version'" +$ldFlag = "-ldflags=-s -w -X 'azure.logicappsstandard/internal/version.Version=$Version' -X 'azure.logicappsstandard/internal/version.Commit=$SourceVersion' -X 'azure.logicappsstandard/internal/version.BuildDate=$(Get-Date -Format o)' " if ($IsWindows) { $msg = "Building for Windows" @@ -55,13 +54,6 @@ if ($IsWindows) { } elseif ($IsLinux) { Write-Host "Building for linux" - - # Disable cgo in the x64 Linux build. This will also statically - # link the resulting binary which increases backwards - # compatibility with older versions of Linux. - if ($env:GOARCH -ne "arm64") { - $env:CGO_ENABLED = "0" - } } elseif ($IsMacOS) { Write-Host "Building for macOS" diff --git a/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 b/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 index 2e66dea3138..cfb399136f3 100644 --- a/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 +++ b/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 @@ -24,4 +24,4 @@ if ($LASTEXITCODE -ne 0) { Write-Host "" Write-Host "All tests passed!" -ForegroundColor Green -exit 0 +exit 0 \ No newline at end of file From dc1349fe0c1fade266c2b6f1244505b843338839 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:47:23 +0000 Subject: [PATCH 24/38] Update build scripts to target azure.logicappsstandard/internal/version --- cli/azd/extensions/azure.logicappsstandard/build.ps1 | 2 +- cli/azd/extensions/azure.logicappsstandard/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/build.ps1 b/cli/azd/extensions/azure.logicappsstandard/build.ps1 index 5ceb60a8bbc..6d782d3e850 100644 --- a/cli/azd/extensions/azure.logicappsstandard/build.ps1 +++ b/cli/azd/extensions/azure.logicappsstandard/build.ps1 @@ -41,7 +41,7 @@ else { ) } -$APP_PATH = "$env:EXTENSION_ID/internal/cmd" +$APP_PATH = "$env:EXTENSION_ID/internal/version" # Loop through platforms and build foreach ($PLATFORM in $PLATFORMS) { diff --git a/cli/azd/extensions/azure.logicappsstandard/build.sh b/cli/azd/extensions/azure.logicappsstandard/build.sh index f1a995ec5e9..28b2f7703fa 100644 --- a/cli/azd/extensions/azure.logicappsstandard/build.sh +++ b/cli/azd/extensions/azure.logicappsstandard/build.sh @@ -33,7 +33,7 @@ else ) fi -APP_PATH="$EXTENSION_ID/internal/cmd" +APP_PATH="$EXTENSION_ID/internal/version" # Loop through platforms and build for PLATFORM in "${PLATFORMS[@]}"; do From d977ea8f30070714deca1e5467b12e5b97dd5592 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 17:53:18 +0000 Subject: [PATCH 25/38] Make azurelogicappsstandard module consistent with other extensions --- cli/azd/extensions/azure.logicappsstandard/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/go.mod b/cli/azd/extensions/azure.logicappsstandard/go.mod index 24c7d99c965..7bd10a9cfb7 100644 --- a/cli/azd/extensions/azure.logicappsstandard/go.mod +++ b/cli/azd/extensions/azure.logicappsstandard/go.mod @@ -1,4 +1,4 @@ -module azure.logicappsstandard +module azurelogicappsstandard go 1.26.1 From d8ef69f372c32b64120f292d395eb859319a07d5 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:01:06 +0000 Subject: [PATCH 26/38] Add pell checker config file to azure.logicappsstandard --- cli/azd/extensions/azure.logicappsstandard/cspell.yaml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cli/azd/extensions/azure.logicappsstandard/cspell.yaml diff --git a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml new file mode 100644 index 00000000000..2d5eb89d0fe --- /dev/null +++ b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml @@ -0,0 +1,4 @@ +import: ../../.vscode/cspell.yaml +words: + - logicappsstandard + \ No newline at end of file From 1cfb2a05bf7133a568096559d3e56d5448cc0838 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:03:08 +0000 Subject: [PATCH 27/38] Fix azurelogicappsstandard imports because . was removed --- .../extensions/azure.logicappsstandard/internal/cmd/listen.go | 2 +- cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go | 2 +- cli/azd/extensions/azure.logicappsstandard/main.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go index c48cc804efe..cf37704f18f 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/azure/azure-dev/cli/azd/pkg/azdext" - "azure.logicappsstandard/internal/project" + "azurelogicappsstandard/internal/project" ) // configureListen is called by NewListenCommand to register event handlers. diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go index eddd9c37a59..70b9f224630 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go @@ -7,7 +7,7 @@ import ( "github.com/azure/azure-dev/cli/azd/pkg/azdext" "github.com/spf13/cobra" - "azure.logicappsstandard/internal/version" + "azurelogicappsstandard/internal/version" ) const ( diff --git a/cli/azd/extensions/azure.logicappsstandard/main.go b/cli/azd/extensions/azure.logicappsstandard/main.go index 32b4f714487..1166cd3800e 100644 --- a/cli/azd/extensions/azure.logicappsstandard/main.go +++ b/cli/azd/extensions/azure.logicappsstandard/main.go @@ -6,7 +6,7 @@ package main import ( "github.com/azure/azure-dev/cli/azd/pkg/azdext" - "azure.logicappsstandard/internal/cmd" + "azurelogicappsstandard/internal/cmd" ) func main() { From 9f9b11eb1f45d154e4ebda6b9d6bbd95d26c2e22 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:03:49 +0000 Subject: [PATCH 28/38] Add azurelogicappsstandard to words for azure.logicappsstandard --- cli/azd/extensions/azure.logicappsstandard/cspell.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml index 2d5eb89d0fe..f87667e82d9 100644 --- a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml +++ b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml @@ -1,4 +1,5 @@ import: ../../.vscode/cspell.yaml words: + - azurelogicappsstandard - logicappsstandard \ No newline at end of file From 4c326f5e49e2782542423f139e2075bb6288f8d0 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:13:54 +0000 Subject: [PATCH 29/38] Implement path resolution validation for custom code projects in Logic Apps Standard Co-authored-by: Copilot --- .../framework_service_logicappsstandard.go | 50 ++++++++++++++++--- ...ramework_service_logicappsstandard_test.go | 22 ++++++++ 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index 3a45313d061..ee816332d86 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -8,6 +8,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/azure/azure-dev/cli/azd/pkg/azdext" ) @@ -130,14 +131,17 @@ func (p *LogicAppsStandardFrameworkServiceProvider) Package( return nil, fmt.Errorf("getting project directory: %w", err) } - // Determine the absolute path to the Logic Apps Standard project based on the project directory - // and the relative path specified in the service configuration. - packagePath := filepath.Join(projectDir, serviceConfig.RelativePath) + packageParts := []string{serviceConfig.RelativePath} - // If an output path (dist) is specified, append it to the package path - // This allows for subdirectories like "Workflows" to be the root of the zip + // If an output path is specified, append it to the package path. + // This allows for subdirectories like "Workflows" to be the root of the zip. if serviceConfig.OutputPath != "" { - packagePath = filepath.Join(packagePath, serviceConfig.OutputPath) + packageParts = append(packageParts, serviceConfig.OutputPath) + } + + packagePath, err := resolvePathWithinBase(projectDir, packageParts...) + if err != nil { + return nil, fmt.Errorf("resolving package path: %w", err) } // Return a DIRECTORY artifact pointing to the project root. @@ -162,11 +166,41 @@ func (p *LogicAppsStandardFrameworkServiceProvider) resolveCustomCodeProjectPath return "", fmt.Errorf("getting project directory: %w", err) } - return filepath.Join( + customCodeProjectPath, err := resolvePathWithinBase( projectDir, serviceConfig.RelativePath, getAdditionalProperty(serviceConfig, "customCodeProject"), - ), nil + ) + if err != nil { + return "", fmt.Errorf("resolving custom code project path: %w", err) + } + + return customCodeProjectPath, nil +} + +// resolvePathWithinBase joins path parts and validates the resolved path remains under baseDir. +func resolvePathWithinBase(baseDir string, pathParts ...string) (string, error) { + baseAbs, err := filepath.Abs(baseDir) + if err != nil { + return "", fmt.Errorf("resolving base directory '%s': %w", baseDir, err) + } + + resolvedPath := filepath.Join(append([]string{baseAbs}, pathParts...)...) + resolvedAbs, err := filepath.Abs(resolvedPath) + if err != nil { + return "", fmt.Errorf("resolving path '%s': %w", resolvedPath, err) + } + + rel, err := filepath.Rel(baseAbs, resolvedAbs) + if err != nil { + return "", fmt.Errorf("getting relative path from '%s' to '%s': %w", baseAbs, resolvedAbs, err) + } + + if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) { + return "", fmt.Errorf("path '%s' is outside project directory '%s'", resolvedAbs, baseAbs) + } + + return resolvedAbs, nil } // getAdditionalProperty retrieves a custom property from the service configuration's additional properties. diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index a18b90414b4..868cc46bbd0 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -153,6 +153,19 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { assert.Contains(t, err.Error(), "custom code project not found") }) }) + + t.Run("fails when custom code project escapes project directory", func(t *testing.T) { + provider := &LogicAppsStandardFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "../../../outside.csproj", + }) + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + err := provider.Initialize(t.Context(), svc) + require.Error(t, err) + assert.Contains(t, err.Error(), "outside project directory") + }) + }) } func TestPackageUsesProjectAndOutputPaths(t *testing.T) { @@ -182,6 +195,15 @@ func TestPackageUsesProjectAndOutputPaths(t *testing.T) { require.NotEmpty(t, result.Artifacts) assert.Equal(t, expectedPath, result.Artifacts[0].Location) }) + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + svc := newServiceConfig("logicApp", "src/logicApp", nil) + svc.OutputPath = "../../../outside" + + _, err := provider.Package(t.Context(), svc, nil, func(string) {}) + require.Error(t, err) + assert.Contains(t, err.Error(), "outside project directory") + }) } func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) { From 7fb1244f6538dde95893798370cdbb04e925595d Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:21:00 +0000 Subject: [PATCH 30/38] Add nil checks and error handling for custom code project properties Co-authored-by: Copilot --- .../framework_service_logicappsstandard.go | 6 +- ...ramework_service_logicappsstandard_test.go | 65 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index ee816332d86..ec5a127b0f3 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -205,11 +205,15 @@ func resolvePathWithinBase(baseDir string, pathParts ...string) (string, error) // getAdditionalProperty retrieves a custom property from the service configuration's additional properties. func getAdditionalProperty(serviceConfig *azdext.ServiceConfig, key string) string { + if serviceConfig == nil { + return "" + } + props := serviceConfig.GetAdditionalProperties() if props == nil { return "" } - if v, ok := props.Fields[key]; ok { + if v, ok := props.Fields[key]; ok && v != nil { return v.GetStringValue() } return "" diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index 868cc46bbd0..5b3610f5b1a 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -17,6 +17,10 @@ import ( ) func TestGetAdditionalProperty(t *testing.T) { + t.Run("returns empty for nil service config", func(t *testing.T) { + assert.Equal(t, "", getAdditionalProperty(nil, "customCodeProject")) + }) + t.Run("returns empty for nil additional properties", func(t *testing.T) { svc := &azdext.ServiceConfig{} assert.Equal(t, "", getAdditionalProperty(svc, "customCodeProject")) @@ -32,6 +36,10 @@ func TestGetAdditionalProperty(t *testing.T) { } func TestHasCustomCodeProjectConfigured(t *testing.T) { + t.Run("returns false for nil service config", func(t *testing.T) { + assert.False(t, hasCustomCodeProjectConfigured(nil)) + }) + t.Run("returns false when customCodeProject is absent", func(t *testing.T) { assert.False(t, hasCustomCodeProjectConfigured(newServiceConfig("logicApp", "src/logicApp", nil))) }) @@ -166,6 +174,19 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { assert.Contains(t, err.Error(), "outside project directory") }) }) + + t.Run("fails when custom code project path is invalid", func(t *testing.T) { + provider := &LogicAppsStandardFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Bad\x00Name.csproj", + }) + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + err := provider.Initialize(t.Context(), svc) + require.Error(t, err) + assert.Contains(t, err.Error(), "custom code project") + }) + }) } func TestPackageUsesProjectAndOutputPaths(t *testing.T) { @@ -276,6 +297,35 @@ func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) { } } +func TestRestoreAndBuildReturnErrorWhenDotNetFails(t *testing.T) { + projectDir := t.TempDir() + createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") + csprojPath := filepath.Join(projectDir, "src/logicApp/Functions/Functions.csproj") + createFile(t, csprojPath, "\n") + + fakeBinDir := t.TempDir() + createFailingFakeDotnetStub(t, fakeBinDir) + + svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{ + "customCodeProject": "Functions/Functions.csproj", + }) + provider := &LogicAppsStandardFrameworkServiceProvider{} + + withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() { + withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() { + _, err := provider.Restore(t.Context(), svc, nil, func(string) {}) + require.Error(t, err) + assert.Contains(t, err.Error(), "restoring custom code project") + assert.Contains(t, err.Error(), csprojPath) + + _, err = provider.Build(t.Context(), svc, nil, func(string) {}) + require.Error(t, err) + assert.Contains(t, err.Error(), "building custom code project") + assert.Contains(t, err.Error(), csprojPath) + }) + }) +} + func newServiceConfig(name, relativePath string, additionalProps map[string]any) *azdext.ServiceConfig { svc := &azdext.ServiceConfig{ Name: name, @@ -328,6 +378,21 @@ func createFakeDotnetStub(t *testing.T, fakeBinDir string) { require.NoError(t, err, "failed writing fake dotnet stub %q", stubPath) } +func createFailingFakeDotnetStub(t *testing.T, fakeBinDir string) { + t.Helper() + stubName := "dotnet" + stubContent := "#!/bin/sh\nexit 1\n" + stubMode := os.FileMode(0o755) + if runtime.GOOS == "windows" { + stubName = "dotnet.cmd" + stubContent = "@echo off\r\nexit /b 1\r\n" + stubMode = 0o644 + } + stubPath := filepath.Join(fakeBinDir, stubName) + err := os.WriteFile(stubPath, []byte(stubContent), stubMode) + require.NoError(t, err, "failed writing failing fake dotnet stub %q", stubPath) +} + func createFile(t *testing.T, filePath, content string) { t.Helper() err := os.MkdirAll(filepath.Dir(filePath), 0o750) From e1a85316c67f5e05efddf4d13fba48475cf6d011 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:38:02 +0000 Subject: [PATCH 31/38] Add documentation for NewRootCommand and NewLogicAppsStandardFrameworkServiceProvider functions Co-authored-by: Copilot --- cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go | 1 + .../internal/project/framework_service_logicappsstandard.go | 1 + 2 files changed, 2 insertions(+) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go index 70b9f224630..f6b1120a3be 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go @@ -14,6 +14,7 @@ const ( extensionID = "azure.logicappsstandard" ) +// NewRootCommand creates the root command for the Logic Apps Standard extension. func NewRootCommand() *cobra.Command { rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{ Name: extensionID, diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index ec5a127b0f3..b41b573e753 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -22,6 +22,7 @@ type LogicAppsStandardFrameworkServiceProvider struct { serviceConfig *azdext.ServiceConfig } +// NewLogicAppsStandardFrameworkServiceProvider creates a Logic Apps Standard framework service provider. func NewLogicAppsStandardFrameworkServiceProvider() azdext.FrameworkServiceProvider { return &LogicAppsStandardFrameworkServiceProvider{} } From f187549d33772d44e52f777aea0eaeeb476ccfff Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 18:57:09 +0000 Subject: [PATCH 32/38] Fix path to version module in build scripts --- cli/azd/extensions/azure.logicappsstandard/build.ps1 | 4 ++-- cli/azd/extensions/azure.logicappsstandard/build.sh | 4 ++-- cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/build.ps1 b/cli/azd/extensions/azure.logicappsstandard/build.ps1 index 6d782d3e850..7e3727a9671 100644 --- a/cli/azd/extensions/azure.logicappsstandard/build.ps1 +++ b/cli/azd/extensions/azure.logicappsstandard/build.ps1 @@ -41,7 +41,7 @@ else { ) } -$APP_PATH = "$env:EXTENSION_ID/internal/version" +$VERSION_PATH = "azurelogicappsstandard/internal/version" # Loop through platforms and build foreach ($PLATFORM in $PLATFORMS) { @@ -65,7 +65,7 @@ foreach ($PLATFORM in $PLATFORMS) { $env:GOARCH = $ARCH go build ` - -ldflags="-X '$APP_PATH.Version=$env:EXTENSION_VERSION' -X '$APP_PATH.Commit=$COMMIT' -X '$APP_PATH.BuildDate=$BUILD_DATE'" ` + -ldflags="-X '$VERSION_PATH.Version=$env:EXTENSION_VERSION' -X '$VERSION_PATH.Commit=$COMMIT' -X '$VERSION_PATH.BuildDate=$BUILD_DATE'" ` -o $OUTPUT_NAME if ($LASTEXITCODE -ne 0) { diff --git a/cli/azd/extensions/azure.logicappsstandard/build.sh b/cli/azd/extensions/azure.logicappsstandard/build.sh index 28b2f7703fa..5e48da51567 100644 --- a/cli/azd/extensions/azure.logicappsstandard/build.sh +++ b/cli/azd/extensions/azure.logicappsstandard/build.sh @@ -33,7 +33,7 @@ else ) fi -APP_PATH="$EXTENSION_ID/internal/version" +VERSION_PATH="azurelogicappsstandard/internal/version" # Loop through platforms and build for PLATFORM in "${PLATFORMS[@]}"; do @@ -53,7 +53,7 @@ for PLATFORM in "${PLATFORMS[@]}"; do # Set environment variables for Go build GOOS=$OS GOARCH=$ARCH go build \ - -ldflags="-X '$APP_PATH.Version=$EXTENSION_VERSION' -X '$APP_PATH.Commit=$COMMIT' -X '$APP_PATH.BuildDate=$BUILD_DATE'" \ + -ldflags="-X '$VERSION_PATH.Version=$EXTENSION_VERSION' -X '$VERSION_PATH.Commit=$COMMIT' -X '$VERSION_PATH.BuildDate=$BUILD_DATE'" \ -o "$OUTPUT_NAME" if [ $? -ne 0 ]; then diff --git a/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 index f419b648e14..8d5753bb803 100644 --- a/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 +++ b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 @@ -46,7 +46,7 @@ $tagsFlag = "-tags=cfi,cfg,osusergo" # -w: Omit DWARF symbol table # -X: Set variable at link time. Used to set the version in source. -$ldFlag = "-ldflags=-s -w -X 'azure.logicappsstandard/internal/version.Version=$Version' -X 'azure.logicappsstandard/internal/version.Commit=$SourceVersion' -X 'azure.logicappsstandard/internal/version.BuildDate=$(Get-Date -Format o)' " +$ldFlag = "-ldflags=-s -w -X 'azurelogicappsstandard/internal/version.Version=$Version' -X 'azurelogicappsstandard/internal/version.Commit=$SourceVersion' -X 'azurelogicappsstandard/internal/version.BuildDate=$(Get-Date -Format o)' " if ($IsWindows) { $msg = "Building for Windows" From 8ced4d700ecdbec5a00f177cc614d68abaf70ad7 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Fri, 1 May 2026 19:00:20 +0000 Subject: [PATCH 33/38] Improve comment about what's packaged --- .../internal/project/framework_service_logicappsstandard.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index b41b573e753..e7e911396fb 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -145,7 +145,7 @@ func (p *LogicAppsStandardFrameworkServiceProvider) Package( return nil, fmt.Errorf("resolving package path: %w", err) } - // Return a DIRECTORY artifact pointing to the project root. + // Return a DIRECTORY artifact pointing to the resolved package directory for the service. // azd's packaging pipeline will handle creating the zip archive from this directory. // By specifying an absolute path, azd will use the host specific ignore file (e.g. .funcignore) for exclusions. return &azdext.ServicePackageResult{ From 77b36cc7b601ea3ef6db06f40958b4b52bf32021 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Sat, 2 May 2026 11:41:27 +0200 Subject: [PATCH 34/38] Add designtime as word to cspell config azure.logicappsstandard --- cli/azd/extensions/azure.logicappsstandard/cspell.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml index f87667e82d9..8f8eb4dbc8e 100644 --- a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml +++ b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml @@ -1,5 +1,6 @@ import: ../../.vscode/cspell.yaml words: - azurelogicappsstandard + - designtime - logicappsstandard \ No newline at end of file From fce74094ccab62df2ad6b17fbe723ae28e2dc649 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Sat, 2 May 2026 15:08:44 +0200 Subject: [PATCH 35/38] Use lowercase for service name and folder in azure.logicappsstandard extension snippets --- .../azure.logicappsstandard/README.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/README.md b/cli/azd/extensions/azure.logicappsstandard/README.md index 3fdef6a16ad..4c3dc0d51af 100644 --- a/cli/azd/extensions/azure.logicappsstandard/README.md +++ b/cli/azd/extensions/azure.logicappsstandard/README.md @@ -25,13 +25,13 @@ For example, if your template has a Logic App Standard project with the followin ``` └── src - └── logicApp + └── logicapp ├── .vscode - ├── Artifacts + ├── artifacts ├── lib - ├── SampleWorkflow1 + ├── workflow1 │ └── workflow.json - ├── SampleWorkflow2 + ├── workflow2 │ └── workflow.json ├── workflow-designtime ├── .funcignore @@ -44,27 +44,27 @@ Use the following snippet in your `azure.yaml` file to configure the Logic App: ```yaml services: - logicApp: - project: ./src/logicApp + logicapp: + project: ./src/logicapp host: function language: logicappsstandard ``` -This will package everything under the `src/logicApp` folder in a .zip file. Because `function` is used as the host, the exclusions in `.funcignore` are respected and only the relevant files are packaged. +This will package everything under the `src/logicapp` folder in a .zip file. Because `function` is used as the host, the exclusions in `.funcignore` are respected and only the relevant files are packaged. The extension also supports Logic App Standard projects with a .NET 8 or .NET Framework custom code project. For example, if your template has a Logic App Standard project with custom code project following this structure: ``` └── src - └── logicApp + └── logicapp ├── Functions │ ├── MyFunctions.cs │ ├── Functions.csproj │ └── ... └── Workflows - ├── SampleWorkflow1 + ├── workflow1 │ └── workflow.json - ├── SampleWorkflow2 + ├── workflow2 │ └── workflow.json ├── host.json └── ... @@ -74,8 +74,8 @@ You can use the following snippet in your `azure.yaml` file to configure the Log ```yaml services: - logicAppSample2: - project: ./src/logicApp + logicapp: + project: ./src/logicapp dist: Workflows host: function language: logicappsstandard From 99f6f7b0ae8f301650888742df745eba883e2eb0 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Mon, 4 May 2026 16:42:50 +0200 Subject: [PATCH 36/38] Add logicapp as word to cspell config azure.logicappsstandard extension --- cli/azd/extensions/azure.logicappsstandard/cspell.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml index 8f8eb4dbc8e..4d8530cabe7 100644 --- a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml +++ b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml @@ -2,5 +2,6 @@ import: ../../.vscode/cspell.yaml words: - azurelogicappsstandard - designtime + - logicapp - logicappsstandard \ No newline at end of file From eed4e0337652e2a7eeec34d4e280fe88f2245dc1 Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Tue, 5 May 2026 16:00:35 +0000 Subject: [PATCH 37/38] Require host to be 'function' when using language 'logicappsstandard' from azure.logicappsstandard extension Co-authored-by: Copilot --- .../project/framework_service_logicappsstandard.go | 4 ++++ .../framework_service_logicappsstandard_test.go | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go index e7e911396fb..42275feda79 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go @@ -34,6 +34,10 @@ func (p *LogicAppsStandardFrameworkServiceProvider) Initialize( ) error { p.serviceConfig = serviceConfig + if serviceConfig.Host != "function" { + return fmt.Errorf("Logic Apps Standard requires the host to be 'function', but found '%s'", serviceConfig.Host) + } + if hasCustomCodeProjectConfigured(serviceConfig) { csProjPath, err := p.resolveCustomCodeProjectPath(serviceConfig) if err != nil { diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go index 5b3610f5b1a..dbdd8d04edd 100644 --- a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go +++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go @@ -110,6 +110,16 @@ func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) { projectDir := t.TempDir() createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n") + t.Run("fails when host is not function", func(t *testing.T) { + provider := &LogicAppsStandardFrameworkServiceProvider{} + svc := newServiceConfig("logicApp", "src/logicApp", nil) + svc.Host = "appservice" + + err := provider.Initialize(t.Context(), svc) + require.Error(t, err) + assert.Equal(t, "Logic Apps Standard requires the host to be 'function', but found 'appservice'", err.Error()) + }) + t.Run("succeeds without customCodeProject and sets serviceConfig", func(t *testing.T) { provider := &LogicAppsStandardFrameworkServiceProvider{} svc := newServiceConfig("logicApp", "src/logicApp", nil) @@ -330,6 +340,7 @@ func newServiceConfig(name, relativePath string, additionalProps map[string]any) svc := &azdext.ServiceConfig{ Name: name, RelativePath: relativePath, + Host: "function", } if additionalProps != nil { From d782cb02bd723351d11e0c6e85f159072864034b Mon Sep 17 00:00:00 2001 From: Ronald Bosma Date: Thu, 21 May 2026 14:41:58 +0000 Subject: [PATCH 38/38] Update to azd v1.25.1 in azure.logicappsstandard extension --- .../extensions/azure.logicappsstandard/go.mod | 34 +++++----- .../extensions/azure.logicappsstandard/go.sum | 68 +++++++++---------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/cli/azd/extensions/azure.logicappsstandard/go.mod b/cli/azd/extensions/azure.logicappsstandard/go.mod index 7bd10a9cfb7..d6c8ffb1842 100644 --- a/cli/azd/extensions/azure.logicappsstandard/go.mod +++ b/cli/azd/extensions/azure.logicappsstandard/go.mod @@ -3,7 +3,7 @@ module azurelogicappsstandard go 1.26.1 require ( - github.com/azure/azure-dev/cli/azd v1.24.2 + github.com/azure/azure-dev/cli/azd v1.25.1 github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.11.1 google.golang.org/protobuf v1.36.11 @@ -18,24 +18,24 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1 // indirect - github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 // indirect + github.com/Masterminds/semver/v3 v3.5.0 // indirect github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b // indirect - github.com/alecthomas/chroma/v2 v2.23.1 // indirect + github.com/alecthomas/chroma/v2 v2.24.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/braydonk/yaml v0.9.0 // indirect github.com/buger/goterm v1.0.4 // indirect - github.com/buger/jsonparser v1.1.2 // indirect + github.com/buger/jsonparser v1.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/glamour v1.0.0 // indirect github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect github.com/charmbracelet/x/ansi v0.11.7 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect - github.com/charmbracelet/x/exp/slice v0.0.0-20260422141420-a6cbdff8a7e2 // indirect + github.com/charmbracelet/x/exp/slice v0.0.0-20260519012233-798e623c8447 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/cli/browser v1.3.0 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect @@ -49,7 +49,7 @@ require ( github.com/gofrs/flock v0.13.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golobby/container/v3 v3.3.2 // indirect - github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/jsonschema-go v0.4.3 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -59,9 +59,9 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.4.0 // indirect - github.com/mark3labs/mcp-go v0.49.0 // indirect + github.com/mark3labs/mcp-go v0.54.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.21 // indirect + github.com/mattn/go-isatty v0.0.22 // indirect github.com/mattn/go-runewidth v0.0.23 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/microcosm-cc/bluemonday v1.0.27 // indirect @@ -91,14 +91,14 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect - golang.org/x/crypto v0.50.0 // indirect - golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect - golang.org/x/net v0.53.0 // indirect - golang.org/x/sys v0.43.0 // indirect - golang.org/x/term v0.42.0 // indirect - golang.org/x/text v0.36.0 // indirect + golang.org/x/crypto v0.51.0 // indirect + golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a // indirect + golang.org/x/net v0.54.0 // indirect + golang.org/x/sys v0.44.0 // indirect + golang.org/x/term v0.43.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 // indirect - google.golang.org/grpc v1.80.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260519071638-aa98bba5eb94 // indirect + google.golang.org/grpc v1.81.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/cli/azd/extensions/azure.logicappsstandard/go.sum b/cli/azd/extensions/azure.logicappsstandard/go.sum index a5786473fe8..f6b13b080f8 100644 --- a/cli/azd/extensions/azure.logicappsstandard/go.sum +++ b/cli/azd/extensions/azure.logicappsstandard/go.sum @@ -25,18 +25,18 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfg github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1 h1:edShSHV3DV90+kt+CMaEXEzR9QF7wFrPJxVGz2blMIU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= -github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= -github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 h1:RHK7bS+HQMslb1sZpAokUt+zTVmue0hKSs2C791hhzU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= +github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b h1:g9SuFmxM/WucQFKTMSP+irxyf5m0RiUJreBDhGI6jSA= github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b/go.mod h1:XjvqMUpGd3Xn9Jtzk/4GEBCSoBX0eB2RyriXgne0IdM= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY= -github.com/alecthomas/chroma/v2 v2.23.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o= +github.com/alecthomas/chroma/v2 v2.24.1 h1:m5ffpfZbIb++k8AqFEKy9uVgY12xIQtBsQlc6DfZJQM= +github.com/alecthomas/chroma/v2 v2.24.1/go.mod h1:l+ohZ9xRXIbGe7cIW+YZgOGbvuVLjMps/FYN/CwuabI= github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -45,8 +45,8 @@ github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWp github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/azure/azure-dev/cli/azd v1.24.2 h1:Y/m9CrjhgNgFoolMU0HmDn358eWB8Cpmh/G2F+5urAQ= -github.com/azure/azure-dev/cli/azd v1.24.2/go.mod h1:YANepMw36aWA8/mQyXau6JCAG84oK0ZgfvLF8rN5asU= +github.com/azure/azure-dev/cli/azd v1.25.1 h1:FLU+KVGwQBmSwADN8GuKQvYdFLpclc8SX6c4md+5b0Y= +github.com/azure/azure-dev/cli/azd v1.25.1/go.mod h1:Q8S2cdn6ArpzaHTjwRFLbGFgS6rU09rOF7k5gsBTTso= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= @@ -59,8 +59,8 @@ github.com/braydonk/yaml v0.9.0 h1:ewGMrVmEVpsm3VwXQDR388sLg5+aQ8Yihp6/hc4m+h4= github.com/braydonk/yaml v0.9.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4= github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY= github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= -github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= -github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/buger/jsonparser v1.2.0 h1:4EFcvK1kD4jyj6YqNK6skK6w+y7FHHBR+XBCtxwu/6g= +github.com/buger/jsonparser v1.2.0/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= @@ -75,8 +75,8 @@ github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMx github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30= github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= -github.com/charmbracelet/x/exp/slice v0.0.0-20260422141420-a6cbdff8a7e2 h1:EXQ7j9kQUGILoSIbxrr1osK9Ca3xqc6EJ7710FIiI3U= -github.com/charmbracelet/x/exp/slice v0.0.0-20260422141420-a6cbdff8a7e2/go.mod h1:vqEfX6xzqW1pKKZUUiFOKg0OQ7bCh54Q2vR/tserrRA= +github.com/charmbracelet/x/exp/slice v0.0.0-20260519012233-798e623c8447 h1:dZNZoFaaoQYXmtAOz4ovm0kISwcKX5Xt29ZLqhNYQKc= +github.com/charmbracelet/x/exp/slice v0.0.0-20260519012233-798e623c8447/go.mod h1:vqEfX6xzqW1pKKZUUiFOKg0OQ7bCh54Q2vR/tserrRA= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo= @@ -119,8 +119,8 @@ github.com/golobby/container/v3 v3.3.2/go.mod h1:RDdKpnKpV1Of11PFBe7Dxc2C1k2KaLE github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= -github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0= +github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= @@ -153,14 +153,14 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mark3labs/mcp-go v0.49.0 h1:7Ssx4d7/T86qnWoJIdye7wEEvUzv39UIbnZb/FqUZMY= -github.com/mark3labs/mcp-go v0.49.0/go.mod h1:BflTAZAzXlrTpiO44gmjMu89n2FO56rJ9m31fp4zd5k= +github.com/mark3labs/mcp-go v0.54.0 h1:PZhQvd+5xrT43cUoiaKn/hDcvLUhcLc1twSEKYPTcTA= +github.com/mark3labs/mcp-go v0.54.0/go.mod h1:+8WclSK1ZUweCP3hvktSji8n8ABG/95QaEkeVE/Uwas= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs= -github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= +github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= +github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= @@ -252,17 +252,17 @@ go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U= go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= -golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= -golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a h1:+3jdDGGB8NGb1Zktc737jlt3/A5f6UlwSzmvqUuufxw= +golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= +golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -276,18 +276,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= -golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -296,10 +296,10 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 h1:XF8+t6QQiS0o9ArVan/HW8Q7cycNPGsJf6GA2nXxYAg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= -google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260519071638-aa98bba5eb94 h1:eZCjr/aAF8c5ccm5pb6T4EXgIei5MlAAPWPJk+5ArfY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260519071638-aa98bba5eb94/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= +google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=