diff --git a/.azure-pipelines/command-metadata-refresh.yml b/.azure-pipelines/command-metadata-refresh.yml new file mode 100644 index 00000000000..205439a46a1 --- /dev/null +++ b/.azure-pipelines/command-metadata-refresh.yml @@ -0,0 +1,150 @@ +# This Yaml Document has been converted by ESAI Yaml Pipeline Conversion Tool. +# Please make sure to check all the converted content, it is your team's responsibility to make sure that the pipeline is still valid and functions as expected. +# This pipeline will be extended to the OneESPT template +# If you are not using the E+D shared hosted pool with windows-2022, replace the pool section with your hosted pool, os, and image name. If you are using a Linux image, you must specify an additional windows image for SDL: https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/sdlanalysis/overview#how-to-specify-a-windows-pool-for-the-sdl-source-analysis-stage +# The Task 'PublishBuildArtifacts@1' has been converted to an output named 'Publish Module Artifacts' in the templateContext section. +# The Task 'NuGetCommand@2' has been converted to an output named 'Publish NuGet to feed' in the templateContext section. + +name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r) +parameters: +- name: BuildAgent + displayName: Build Agent + default: 1es-windows-ps-compute-m +- name: BaseBranch + displayName: Base Branch + default: main +- name: Test + type: boolean + default: true +- name: Pack + type: boolean + default: false +- name: Sign + type: boolean + default: false +- name: BumpModuleVersion + type: boolean + default: false +- name: CreatePullRequest + type: boolean + default: true + +variables: + BuildAgent: ${{ parameters.BuildAgent }} + Branch: "ModuleCommandMetadataRefresh" + BaseBranch: ${{ parameters.BaseBranch }} + +trigger: + branches: + include: + - main + +resources: + repositories: + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + pool: $(BuildAgent) + sdl: + binskim: + enabled: false + justificationForDisabling: "Binskim keeps on crashing and failing the weekly build pipeline. Disabling it for now because we are unable to publish the artifacts to internal feeds." + credscan: + suppressionsFile: $(Build.SourcesDirectory)/.azure-pipelines/config/credscan/credscan-suppressions.json + policheck: + exclusionFile: $(Build.SourcesDirectory)/.azure-pipelines/config/policheck/policheck-exclusions.xml + customBuildTags: + - ES365AIMigrationTooling + stages: + - stage: stage + jobs: + - job: CreateMetadataRefreshBranch + displayName: Create Metadata Refresh Branch + timeoutInMinutes: 1200 + steps: + - template: .azure-pipelines/common-templates/checkout.yml@self + parameters: + TargetBranch: ${{ parameters.BaseBranch }} + - task: PowerShell@2 + name: "ComputeBranch" + displayName: "Compute Module Command Metadata Refresh Branch Name" + inputs: + targetType: inline + script: | + $branch = "{0}/{1}" -f "$(Branch)", (Get-Date -Format yyyyMMddHHmm) + Write-Host "##vso[task.setvariable variable=RefreshBranch;isOutput=true]$branch" + - task: Bash@3 + displayName: "Create Module Command Metadata Refresh Branch" + inputs: + targetType: inline + script: | + git status + git branch $(ComputeBranch.RefreshBranch) + git checkout $(ComputeBranch.RefreshBranch) + git status + + - job: MsGraphPsSdkModuleCommandMetadataGeneration + dependsOn: CreateMetadataRefreshBranch + displayName: Microsoft Graph PowerShell SDK Generation + condition: succeeded() + timeoutInMinutes: 840 + variables: + RefreshBranch: $[ dependencies.CreateMetadataRefreshBranch.outputs['ComputeBranch.RefreshBranch'] ] + steps: + - template: .azure-pipelines/common-templates/checkout.yml@self + parameters: + TargetBranch: $(RefreshBranch) + - template: .azure-pipelines/common-templates/install-tools.yml@self + - template: .azure-pipelines/common-templates/security-pre-checks.yml@self + - template: .azure-pipelines/generation-templates/authentication-module.yml@self + parameters: + Test: ${{ parameters.Test }} + Pack: ${{ parameters.Pack }} + Sign: ${{ parameters.Sign }} + - template: .azure-pipelines/generation-templates/workload-modules.yml@self + parameters: + Test: ${{ parameters.Test }} + Pack: ${{ parameters.Pack }} + Sign: ${{ parameters.Sign }} + - template: .azure-pipelines/generation-templates/meta-module.yml@self + parameters: + Test: ${{ parameters.Test }} + Pack: ${{ parameters.Pack }} + Sign: ${{ parameters.Sign }} + - template: .azure-pipelines/generation-templates/generate-command-metadata.yml@self + - template: .azure-pipelines/common-templates/security-post-checks.yml@self + + - ${{ if eq(parameters.BumpModuleVersion, true) }}: + - task: PowerShell@2 + name: CalculateAndBumpModuleVersion + displayName: Calculate and bump module version + condition: succeeded() + inputs: + pwsh: true + targetType: inline + script: | + . "$(System.DefaultWorkingDirectory)\tools\Versions\BumpModuleVersion.ps1" -BumpV1Module -BumpBetaModule -BumpAuthModule -Debug + - task: Bash@3 + displayName: Push version bump changes + env: + GITHUB_TOKEN: $(GITHUB_TOKEN) + inputs: + targetType: inline + script: | + git status + git add "$(System.DefaultWorkingDirectory)/config/ModuleMetadata.json" + git commit -m 'Bump module versions after metadata generation.' + git push "https://$(GITHUB_TOKEN)@github.com/microsoftgraph/msgraph-sdk-powershell.git" + git status + + - ${{ if eq(parameters.CreatePullRequest, true) }}: + - template: .azure-pipelines/common-templates/create-pr.yml@self + parameters: + BaseBranch: $(BaseBranch) + TargetBranch: $(RefreshBranch) + Title: "[v2] Module Command Metadata Refresh" + Body: "This pull request was automatically created by Azure Pipelines. **Important** Check for unexpected deletions or changes in this PR." \ No newline at end of file diff --git a/.azure-pipelines/common-templates/create-pr.yml b/.azure-pipelines/common-templates/create-pr.yml index 337a46b5b5e..7c572b93c23 100644 --- a/.azure-pipelines/common-templates/create-pr.yml +++ b/.azure-pipelines/common-templates/create-pr.yml @@ -4,7 +4,7 @@ parameters: - name: BaseBranch type: string - default: dev + default: main - name: TargetBranch type: string default: "" diff --git a/.azure-pipelines/common-templates/download-openapi-docs.yml b/.azure-pipelines/common-templates/download-openapi-docs.yml index 9a0a1c58053..11da451a6e9 100644 --- a/.azure-pipelines/common-templates/download-openapi-docs.yml +++ b/.azure-pipelines/common-templates/download-openapi-docs.yml @@ -4,15 +4,11 @@ parameters: - name: Branch type: string + default: "WeeklyApiRefresh" - name: BaseBranch type: string - name: BuildAgent displayName: Build Agent - - name: SkipForceRefresh - type: string - - name: SkipOpenAPIDocsDownload - type: boolean - default: false steps: - template: ./checkout.yml @@ -23,12 +19,16 @@ steps: - task: PowerShell@2 name: "ComputeBranch" - displayName: "Compute weekly branch name" + displayName: "Compute weekly branch name and set Branch variable" inputs: targetType: inline script: | - $branch = "{0}/{1}" -f "$(Branch)", (Get-Date -Format yyyyMMddHHmm) - Write-Host "##vso[task.setvariable variable=WeeklyBranch;isOutput=true]$branch" + $branch = "{0}/{1}" -f "${{ parameters.Branch }}", (Get-Date -Format yyyyMMddHHmm) + Write-Host "Computed weekly branch: $branch" + # Set the Branch pipeline variable for current job + Write-Host "##vso[task.setvariable variable=Branch;isOutput=false]$branch" + # Set the Branch variable as output for subsequent jobs + Write-Host "##vso[task.setvariable variable=Branch;isOutput=true]$branch" - task: Bash@3 displayName: "Create weekly branch" @@ -36,61 +36,31 @@ steps: targetType: inline script: | git status - git branch $(ComputeBranch.WeeklyBranch) - git checkout $(ComputeBranch.WeeklyBranch) + git branch $(Branch) + git checkout $(Branch) git status - task: PowerShell@2 displayName: Download v1.0 OpenApi docs - condition: and(succeeded(), eq('${{ parameters.SkipOpenAPIDocsDownload }}', false)) continueOnError: false inputs: filePath: "$(System.DefaultWorkingDirectory)/tools/UpdateOpenApi.ps1" - arguments: -SkipForceRefresh:$$(SkipForceRefresh) pwsh: true - task: PowerShell@2 displayName: Download beta OpenApi docs - condition: and(succeeded(), eq('${{ parameters.SkipOpenAPIDocsDownload }}', false)) continueOnError: false inputs: filePath: "$(System.DefaultWorkingDirectory)/tools/UpdateOpenApi.ps1" - arguments: -BetaGraphVersion -SkipForceRefresh:$$(SkipForceRefresh) + arguments: -BetaGraphVersion pwsh: true - task: PowerShell@2 name: OpenAPIDocDiff - displayName: Get OpenAPI docs diff - inputs: - pwsh: true - targetType: "inline" - script: | - Write-Host "SkipOpenAPIDocsDownload: ${{ parameters.SkipOpenAPIDocsDownload }}" - if ('${{ parameters.SkipOpenAPIDocsDownload }}' -eq 'True') { - $ModuleNames = "Skipped" - Write-Warning "Skipped OpenAPI Docs Download." - } else { - $diff = git diff --name-only - $ModulesWithChanges = @{} - $diff | %{ - if (($_ -match 'openApiDocs\/(v1.0|beta)\/(.*).yml') -and !$ModulesWithChanges.ContainsKey($matches.2)) - { - $ModulesWithChanges.Add($matches.2, $matches.1) - } - } - $ModuleNames = $ModulesWithChanges.Keys - } - Write-Host "##vso[task.setvariable variable=ModulesWithChanges;isOutput=true]$ModuleNames" - - - task: PowerShell@2 - name: CalculateAndBumpModuleVersion - displayName: Calculate and bump module version - condition: and(succeeded(), ne(variables['OpenAPIDocDiff.ModulesWithChanges'], '')) + displayName: Get OpenAPI docs diff and set ModuleGenerationList variable inputs: + filePath: "$(System.DefaultWorkingDirectory)/tools/Utilities/OpenApiDocDiff.ps1" pwsh: true - targetType: inline - script: | - . "$(System.DefaultWorkingDirectory)\tools\Versions\BumpModuleVersion.ps1" -BumpV1Module -BumpBetaModule -BumpAuthModule -Debug - task: PowerShell@2 name: BuildOpenApiMetadataDetectionTool @@ -112,7 +82,7 @@ steps: - task: Bash@3 displayName: Commit downloaded files - condition: and(succeeded(), ne(variables['OpenAPIDocDiff.ModulesWithChanges'], '')) + condition: and(succeeded(), ne(variables['ModuleGenerationList'], '')) env: GITHUB_TOKEN: $(GITHUB_TOKEN) inputs: @@ -122,10 +92,10 @@ steps: git add . git commit -m 'Weekly OpenApiDocs Download.' git status - git push --set-upstream "https://$(GITHUB_TOKEN)@github.com/microsoftgraph/msgraph-sdk-powershell.git" $(ComputeBranch.WeeklyBranch) + git push --set-upstream "https://$(GITHUB_TOKEN)@github.com/microsoftgraph/msgraph-sdk-powershell.git" $(Branch) git status # References # [0] https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables # [1] https://hub.github.com/hub-pull-request.1.html -# https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token +# https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token \ No newline at end of file diff --git a/.azure-pipelines/generation-templates/individual-workload-module.yml b/.azure-pipelines/generation-templates/individual-workload-module.yml new file mode 100644 index 00000000000..3f461e6ec2c --- /dev/null +++ b/.azure-pipelines/generation-templates/individual-workload-module.yml @@ -0,0 +1,48 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + + +parameters: + - name: Test + type: boolean + default: true + - name: ModuleName + type: string + default: "" + - name: ModuleVersion + type: string + default: "" + - name: Pack + type: boolean + default: true + - name: Sign + type: boolean + default: true + +steps: + - task: PowerShell@2 + displayName: Generate Workload Modules + inputs: + targetType: inline + pwsh: true + script: | + . $(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1 -EnableSigning:$${{ parameters.Sign }} -Build -ExcludeExampleTemplates -ExcludeNotesSection -ModuleToGenerate ${{ parameters.ModuleName }} -ApiVersion ${{ parameters.ModuleVersion }} + - template: ../common-templates/guardian-analyzer.yml + + - task: PowerShell@2 + displayName: Test Workload Modules + enabled: false + inputs: + targetType: inline + pwsh: true + script: | + . $(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1 -SkipGeneration -Test -ModuleToGenerate ${{ parameters.ModuleName }} -ApiVersion ${{ parameters.ModuleVersion }} + + - task: PowerShell@2 + displayName: Find Duplicate Commands + inputs: + targetType: inline + pwsh: true + script: | + . $(System.DefaultWorkingDirectory)/tools/PostGeneration/FindDuplicateCommand.ps1 -SourcePath "$(System.DefaultWorkingDirectory)/src/" + \ No newline at end of file diff --git a/.azure-pipelines/weekly-generation.yml b/.azure-pipelines/weekly-generation.yml index 60e36a5188b..f8b8c04b994 100644 --- a/.azure-pipelines/weekly-generation.yml +++ b/.azure-pipelines/weekly-generation.yml @@ -14,8 +14,8 @@ parameters: - name: BaseBranch displayName: Base Branch default: main -- name: SkipForceRefresh - displayName: Skip Force Refresh +- name: SkipOpenAPIDocsDownload + displayName: Skip OpenAPI Docs Download (also skips branch creation and PR) default: false type: boolean - name: Test @@ -30,15 +30,20 @@ parameters: - name: CreatePullRequest type: boolean default: true -- name: SkipOpenAPIDocsDownload - displayName: Skip OpenAPI Docs Download +- name: SpecifyModules + displayName: Specify Modules to Generate default: false type: boolean +- name: ModulesToGenerate + displayName: Modules To Generate + default: Insert Module Names Here separated by space, e.g., Users_v1.0 Users_beta + type: string + variables: - Branch: "WeeklyApiRefresh" + Branch: "" BaseBranch: ${{ parameters.BaseBranch }} BuildAgent: ${{ parameters.BuildAgent }} - SkipForceRefresh: ${{ parameters.SkipForceRefresh }} + ModuleGenerationList: "${{ parameters.ModulesToGenerate }}" trigger: none pr: none schedules: @@ -73,6 +78,7 @@ extends: jobs: - job: RefreshOpenAPIDocuments displayName: Refresh OpenApi documents + condition: eq(${{ parameters.SkipOpenAPIDocsDownload }}, false) timeoutInMinutes: 1200 steps: - template: .azure-pipelines/common-templates/download-openapi-docs.yml@self @@ -80,34 +86,53 @@ extends: Branch: $(Branch) BaseBranch: $(BaseBranch) BuildAgent: $(BuildAgent) - SkipForceRefresh: $(SkipForceRefresh) - SkipOpenAPIDocsDownload: ${{ parameters.SkipOpenAPIDocsDownload }} + + - job: SetUpModuleMatrix + displayName: Setup Module JSON for Matrix + ${{ if eq(parameters.SkipOpenAPIDocsDownload, false) }}: + dependsOn: RefreshOpenAPIDocuments + condition: and(succeeded(), ne(variables['ModuleGenerationList'], '')) + timeoutInMinutes: 840 + steps: + - task: PowerShell@2 + name: CreateMatrixJson + displayName: Create Matrix Json + inputs: + targetType: inline + pwsh: true + script: | + $modules = "$(ModuleGenerationList)" + Write-Host "Using ModuleGenerationList: $modules" + & "$(System.DefaultWorkingDirectory)/tools/utilities/CreateGenerationMatrix.ps1" -ModuleNames $modules + - job: MsGraphPsSdkWeeklyGeneration - dependsOn: RefreshOpenAPIDocuments + ${{ if eq(parameters.SkipOpenAPIDocsDownload, false) }}: + dependsOn: + - SetUpModuleMatrix + - RefreshOpenAPIDocuments + ${{ else }}: + dependsOn: SetUpModuleMatrix displayName: Microsoft Graph PowerShell SDK Generation - condition: and(succeeded(), ne(dependencies.RefreshOpenAPIDocuments.outputs['OpenAPIDocDiff.ModulesWithChanges'], '')) + condition: succeeded() timeoutInMinutes: 840 variables: - WeeklyBranch: $[ dependencies.RefreshOpenAPIDocuments.outputs['ComputeBranch.WeeklyBranch'] ] + ModulesMatrix: $[ dependencies.SetUpModuleMatrix.outputs['CreateMatrixJson.matrixJson'] ] + ${{ if eq(parameters.SkipOpenAPIDocsDownload, false) }}: + Branch: $[ dependencies.RefreshOpenAPIDocuments.outputs['ComputeBranch.Branch'] ] templateContext: outputs: - ${{ if and(eq(parameters.Pack, true), eq(parameters.Sign, true)) }}: - output: pipelineArtifact displayName: 'Publish Module Artifacts' targetPath: "$(Build.ArtifactStagingDirectory)" - artifactName: "drop" + artifactName: "$(moduleName)_$(moduleVersion)_drop" publishLocation: "Container" - - ${{ if and(eq(parameters.Pack, true), eq(parameters.Sign, true)) }}: - - output: nuget - displayName: 'Publish NuGet to feed' - packageParentPath: '$(Build.ArtifactStagingDirectory)' - packagesToPush: $(Build.ArtifactStagingDirectory)/**/Microsoft.Graph.*.nupkg - publishVstsFeed: $(PROJECT_NAME)/$(FEED_NAME) - allowPackageConflicts: true + strategy: + matrix: $[ dependencies.SetUpModuleMatrix.outputs['CreateMatrixJson.matrixJson'] ] steps: - template: .azure-pipelines/common-templates/checkout.yml@self parameters: - TargetBranch: $(WeeklyBranch) + TargetBranch: $(Branch) - template: .azure-pipelines/common-templates/install-tools.yml@self - template: .azure-pipelines/common-templates/security-pre-checks.yml@self - template: .azure-pipelines/generation-templates/authentication-module.yml@self @@ -115,27 +140,30 @@ extends: Test: ${{ parameters.Test }} Pack: ${{ parameters.Pack }} Sign: ${{ parameters.Sign }} - - template: .azure-pipelines/generation-templates/workload-modules.yml@self + - template: .azure-pipelines/generation-templates/individual-workload-module.yml@self parameters: Test: ${{ parameters.Test }} Pack: ${{ parameters.Pack }} Sign: ${{ parameters.Sign }} - - template: .azure-pipelines/generation-templates/meta-module.yml@self - parameters: - Test: ${{ parameters.Test }} - Pack: ${{ parameters.Pack }} - Sign: ${{ parameters.Sign }} - - ${{ if and(eq(parameters.Pack, true), eq(parameters.Sign, true)) }}: - - template: .azure-pipelines/common-templates/esrp/codesign-nuget.yml@self - parameters: - FolderPath: "$(Build.ArtifactStagingDirectory)" - Pattern: "Microsoft.Graph*.nupkg" - - template: .azure-pipelines/generation-templates/generate-command-metadata.yml@self + ModuleName: $(moduleName) + ModuleVersion: $(moduleVersion) - template: .azure-pipelines/common-templates/security-post-checks.yml@self - - ${{ if eq(parameters.CreatePullRequest, true) }}: - - template: .azure-pipelines/common-templates/create-pr.yml@self - parameters: - BaseBranch: $(BaseBranch) - TargetBranch: $(WeeklyBranch) - Title: "[v2] Weekly OpenApiDocs Refresh" - Body: "This pull request was automatically created by Azure Pipelines. **Important** Check for unexpected deletions or changes in this PR." \ No newline at end of file + + - job: CreatePullRequest + displayName: Create Pull Request for all changes + dependsOn: + - MsGraphPsSdkWeeklyGeneration + - RefreshOpenAPIDocuments + condition: and(succeeded(), eq(dependencies.MsGraphPsSdkWeeklyGeneration.result, 'Succeeded'), eq(${{ parameters.CreatePullRequest }}, true), eq(${{ parameters.SkipOpenAPIDocsDownload }}, false)) + variables: + Branch: $[ dependencies.RefreshOpenAPIDocuments.outputs['ComputeBranch.Branch'] ] + steps: + - template: .azure-pipelines/common-templates/checkout.yml@self + parameters: + TargetBranch: $(Branch) + - template: .azure-pipelines/common-templates/create-pr.yml@self + parameters: + BaseBranch: $(BaseBranch) + TargetBranch: $(Branch) + Title: "[v2] Weekly OpenApiDocs Refresh" + Body: "This pull request was automatically created by Azure Pipelines. **Important** Check for unexpected deletions or changes in this PR." \ No newline at end of file diff --git a/.github/workflows/metadatachanges.yml b/.github/workflows/metadatachanges.yml index d91394e2ecf..687f9db9bf6 100644 --- a/.github/workflows/metadatachanges.yml +++ b/.github/workflows/metadatachanges.yml @@ -7,7 +7,7 @@ on: workflow_dispatch: pull_request: branches: - - dev + - main paths: - openApiDocs/** - src/Authentication/Authentication/custom/common/MgCommandMetadata.json diff --git a/tools/Utilities/CreateGenerationMatrix.ps1 b/tools/Utilities/CreateGenerationMatrix.ps1 new file mode 100644 index 00000000000..86110e68ebe --- /dev/null +++ b/tools/Utilities/CreateGenerationMatrix.ps1 @@ -0,0 +1,79 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.SYNOPSIS + Creates a JSON matrix for Azure DevOps parallel module generation. + +.DESCRIPTION + This script takes a space-separated list of module names and converts them into a JSON matrix + for use with Azure DevOps matrix strategy. If a module name doesn't include a version suffix, + it creates entries for both v1.0 and beta versions. + +.PARAMETER ModuleNames + Space-separated string of module names. Can include version suffixes (e.g., "Users_v1.0") or not (e.g., "Users"). + If no version suffix is provided, both v1.0 and beta entries will be created. + +.PARAMETER OutputVariable + The name of the Azure DevOps output variable to set. If not provided, the JSON is written to the pipeline. + +.EXAMPLE + .\CreateGenerationMatrix.ps1 -ModuleNames "Users Groups" + Creates matrix with Users_v1.0, Users_beta, Groups_v1.0, Groups_beta + +.EXAMPLE + .\CreateGenerationMatrix.ps1 -ModuleNames "Users_v1.0 Groups_beta" + Creates matrix with only Users_v1.0 and Groups_beta +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $ModuleNames, + + [Parameter(Mandatory = $false)] + [string] $OutputVariable = "matrixJson" +) + +Write-Host "ModulesToUpdate: $ModuleNames" + +# Split the input string into an array +$testDataArray = $ModuleNames -split ' ' +$jsonOutput = @{} + +foreach ($item in $testDataArray) { + # Skip empty entries + if ([string]::IsNullOrWhiteSpace($item)) { + continue + } + + if ($item -notmatch '_') { + # If '_' is not present, create two versions: v1.0 and beta + $jsonOutput["${item}_v1.0"] = @{ + moduleVersion = 'v1.0' + moduleName = $item + } + $jsonOutput["${item}_beta"] = @{ + moduleVersion = 'beta' + moduleName = $item + } + } + else { + # Split on '_' to get name and version + $name, $version = $item -split '_' + $jsonOutput[$item] = @{ + moduleVersion = $version + moduleName = $name + } + } +} + +# Convert to compressed JSON +$result = $jsonOutput | ConvertTo-Json -Compress + +Write-Host "Generated matrix JSON:" +Write-Host $result + +# Set Azure DevOps output variable +Write-Host "##vso[task.setvariable variable=$OutputVariable;isOutput=true]$result" diff --git a/tools/Utilities/OpenApiDocDiff.ps1 b/tools/Utilities/OpenApiDocDiff.ps1 new file mode 100644 index 00000000000..90488eb6fd3 --- /dev/null +++ b/tools/Utilities/OpenApiDocDiff.ps1 @@ -0,0 +1,56 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.SYNOPSIS + Detects changes in OpenAPI documentation files and outputs the list of affected modules. + +.DESCRIPTION + This script performs a git diff to identify which OpenAPI YAML files have changed, + extracts the module names and versions from the file paths, and outputs a space-separated + list of modules that need to be regenerated. + +.PARAMETER OutputVariable + The name of the Azure DevOps pipeline variable to set with the results. + Default is "ModuleGenerationList". + +.EXAMPLE + .\OpenApiDocDiff.ps1 + Detects changes and sets the ModuleGenerationList pipeline variable. + +.EXAMPLE + .\OpenApiDocDiff.ps1 -OutputVariable "ChangedModules" + Detects changes and sets the ChangedModules pipeline variable. +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [string] $OutputVariable = "ModuleGenerationList" +) + +# Get the list of changed files from git +$diff = git diff --name-only +$ModulesWithChanges = @{} + +# Parse each changed file path +$diff | ForEach-Object { + # Match OpenAPI docs paths: openApiDocs/(v1.0|beta)/{ModuleName}.yml + if ($_ -match 'openApiDocs\/(v1.0|beta)\/(.*)\.yml') { + $version = if ($matches[1] -eq 'v1.0') { 'v1.0' } else { 'beta' } + $moduleName = "$($matches[2])_$version" + + # Add to hashtable if not already present + if (!$ModulesWithChanges.ContainsKey($moduleName)) { + $ModulesWithChanges.Add($moduleName, $matches[1]) + } + } +} + +# Convert hashtable keys to space-separated string +$ModuleNames = $ModulesWithChanges.Keys + +Write-Host "Modules with changes: $ModuleNames" + +# Set the pipeline variable +Write-Host "##vso[task.setvariable variable=$OutputVariable;isOutput=false]$ModuleNames"