diff --git a/eng/common/TestResources/New-TestResources.ps1 b/eng/common/TestResources/New-TestResources.ps1 index 0552f9dd5e7b..3201f5175483 100644 --- a/eng/common/TestResources/New-TestResources.ps1 +++ b/eng/common/TestResources/New-TestResources.ps1 @@ -15,9 +15,6 @@ param ( [ValidatePattern('^[-a-zA-Z0-9\.\(\)_]{0,80}(?<=[a-zA-Z0-9\(\)])$')] [string] $BaseName, - [ValidatePattern('^[-\w\._\(\)]+$')] - [string] $ResourceGroupName, - [Parameter(Mandatory = $true)] [string] $ServiceDirectory, @@ -118,7 +115,6 @@ $repositoryRoot = "$PSScriptRoot/../../.." | Resolve-Path $root = [System.IO.Path]::Combine($repositoryRoot, "sdk", $ServiceDirectory) | Resolve-Path $templateFileName = 'test-resources.json' $templateFiles = @() -$environmentVariables = @{} Write-Verbose "Checking for '$templateFileName' files under '$root'" Get-ChildItem -Path $root -Filter $templateFileName -Recurse | ForEach-Object { @@ -198,18 +194,14 @@ $serviceName = if (Split-Path -IsAbsolute $ServiceDirectory) { $ServiceDirectory } -if ($CI) { - $BaseName = 't' + (New-Guid).ToString('n').Substring(0, 16) - Write-Verbose "Generated base name '$BaseName' for CI build" -} +# Format the resource group name based on resource group naming recommendations and limitations. +$resourceGroupName = if ($CI) { + $BaseName = 't' + (New-Guid).ToString('n').Substring(0, 16) + Write-Verbose "Generated base name '$BaseName' for CI build" -$ResourceGroupName = if ($ResourceGroupName) { - $ResourceGroupName -} elseif ($CI) { - # Format the resource group name based on resource group naming recommendations and limitations. - "rg-{0}-$BaseName" -f ($serviceName -replace '[\\\/:]', '-').Substring(0, [Math]::Min($serviceName.Length, 90 - $BaseName.Length - 4)).Trim('-') + "rg-{0}-$BaseName" -f ($serviceName -replace '[\\\/:]', '-').Substring(0, [Math]::Min($serviceName.Length, 90 - $BaseName.Length - 4)).Trim('-') } else { - "rg-$BaseName" + "rg-$BaseName" } # Tag the resource group to be deleted after a certain number of hours if specified. @@ -233,14 +225,13 @@ if ($CI) { } # Set the resource group name variable. - Write-Host "Setting variable 'AZURE_RESOURCEGROUP_NAME': $ResourceGroupName" - Write-Host "##vso[task.setvariable variable=AZURE_RESOURCEGROUP_NAME;]$ResourceGroupName" - $environmentVariables['AZURE_RESOURCEGROUP_NAME'] = $ResourceGroupName + Write-Host "Setting variable 'AZURE_RESOURCEGROUP_NAME': $resourceGroupName" + Write-Host "##vso[task.setvariable variable=AZURE_RESOURCEGROUP_NAME;]$resourceGroupName" } -Log "Creating resource group '$ResourceGroupName' in location '$Location'" +Log "Creating resource group '$resourceGroupName' in location '$Location'" $resourceGroup = Retry { - New-AzResourceGroup -Name "$ResourceGroupName" -Location $Location -Tag $tags -Force:$Force + New-AzResourceGroup -Name "$resourceGroupName" -Location $Location -Tag $tags -Force:$Force } if ($resourceGroup.ProvisioningState -eq 'Succeeded') { @@ -304,7 +295,7 @@ foreach ($templateFile in $templateFiles) { $preDeploymentScript = $templateFile | Split-Path | Join-Path -ChildPath 'test-resources-pre.ps1' if (Test-Path $preDeploymentScript) { Log "Invoking pre-deployment script '$preDeploymentScript'" - &$preDeploymentScript -ResourceGroupName $ResourceGroupName @PSBoundParameters + &$preDeploymentScript -ResourceGroupName $resourceGroupName @PSBoundParameters } Log "Deploying template '$templateFile' to resource group '$($resourceGroup.ResourceGroupName)'" @@ -373,7 +364,6 @@ foreach ($templateFile in $templateFiles) { foreach ($key in $deploymentOutputs.Keys) { $value = $deploymentOutputs[$key] - $environmentVariables[$key] = $value if ($CI) { # Treat all ARM template output variables as secrets since "SecureString" variables do not set values. @@ -396,14 +386,12 @@ foreach ($templateFile in $templateFiles) { $postDeploymentScript = $templateFile | Split-Path | Join-Path -ChildPath 'test-resources-post.ps1' if (Test-Path $postDeploymentScript) { Log "Invoking post-deployment script '$postDeploymentScript'" - &$postDeploymentScript -ResourceGroupName $ResourceGroupName -DeploymentOutputs $deploymentOutputs @PSBoundParameters + &$postDeploymentScript -ResourceGroupName $resourceGroupName -DeploymentOutputs $deploymentOutputs @PSBoundParameters } } $exitActions.Invoke() -return $environmentVariables - <# .SYNOPSIS Deploys live test resources defined for a service directory to Azure. @@ -434,10 +422,6 @@ the ARM template. See also https://docs.microsoft.com/azure/architecture/best-pr Note: The value specified for this parameter will be overriden and generated by New-TestResources.ps1 if $CI is specified. -.PARAMETER ResourceGroupName -Set this value to deploy directly to a Resource Group that has already been -created. - .PARAMETER ServiceDirectory A directory under 'sdk' in the repository root - optionally with subdirectories specified - in which to discover ARM templates named 'test-resources.json'. diff --git a/eng/common/TestResources/New-TestResources.ps1.md b/eng/common/TestResources/New-TestResources.ps1.md index d4479294d381..e12f0a30dc04 100644 --- a/eng/common/TestResources/New-TestResources.ps1.md +++ b/eng/common/TestResources/New-TestResources.ps1.md @@ -8,30 +8,33 @@ schema: 2.0.0 # New-TestResources.ps1 ## SYNOPSIS + Deploys live test resources defined for a service directory to Azure. ## SYNTAX ### Default (Default) -``` -New-TestResources.ps1 [-BaseName] [-ResourceGroupName ] -ServiceDirectory - -TestApplicationId [-TestApplicationSecret ] [-TestApplicationOid ] - [-DeleteAfterHours ] [-Location ] [-Environment ] [-AdditionalParameters ] - [-CI] [-Force] [-OutFile] [-WhatIf] [-Confirm] [] + +```text +New-TestResources.ps1 [-BaseName] -ServiceDirectory -TestApplicationId + [-TestApplicationSecret ] [-TestApplicationOid ] [-DeleteAfterHours ] + [-Location ] [-Environment ] [-AdditionalParameters ] [-CI] [-Force] [-WhatIf] + [-Confirm] [] ``` ### Provisioner -``` -New-TestResources.ps1 [-BaseName] [-ResourceGroupName ] -ServiceDirectory - -TestApplicationId [-TestApplicationSecret ] [-TestApplicationOid ] - -TenantId [-SubscriptionId ] -ProvisionerApplicationId - -ProvisionerApplicationSecret [-DeleteAfterHours ] [-Location ] - [-Environment ] [-AdditionalParameters ] [-CI] [-Force] [-OutFile] [-WhatIf] [-Confirm] - [] + +```text +New-TestResources.ps1 [-BaseName] -ServiceDirectory -TestApplicationId + [-TestApplicationSecret ] [-TestApplicationOid ] -TenantId [-SubscriptionId ] + -ProvisionerApplicationId -ProvisionerApplicationSecret [-DeleteAfterHours ] + [-Location ] [-Environment ] [-AdditionalParameters ] [-CI] [-Force] [-WhatIf] + [-Confirm] [] ``` ## DESCRIPTION -Deploys live test resouces specified in test-resources.json files to a resource + +Deploys live test resources specified in test-resources.json files to a resource group. This script searches the directory specified in $ServiceDirectory recursively @@ -53,7 +56,8 @@ specified in $ProvisionerApplicationId and $ProvisionerApplicationSecret. ## EXAMPLES ### EXAMPLE 1 -``` + +```text Connect-AzAccount -Subscription "REPLACE_WITH_SUBSCRIPTION_ID" $testAadApp = New-AzADServicePrincipal -Role Owner -DisplayName 'azure-sdk-live-test-app' New-TestResources.ps1 ` @@ -70,7 +74,8 @@ Requires PowerShell 7 to use ConvertFrom-SecureString -AsPlainText or convert the SecureString to plaintext by another means. ### EXAMPLE 2 -``` + +```text New-TestResources.ps1 ` -BaseName 'Generated' ` -ServiceDirectory '$(ServiceDirectory)' ` @@ -85,7 +90,7 @@ New-TestResources.ps1 ` -Verbose ``` -Run this in an Azure DevOps CI (with approrpiate variables configured) before +Run this in an Azure DevOps CI (with appropriate variables configured) before executing live tests. The script will output variables as secrets (to enable log redaction). @@ -93,12 +98,13 @@ log redaction). ## PARAMETERS ### -BaseName + A name to use in the resource group and passed to the ARM template as 'baseName'. Limit $BaseName to enough characters to be under limit plus prefixes specified in the ARM template. See also https://docs.microsoft.com/azure/architecture/best-practices/resource-naming -Note: The value specified for this parameter will be overriden and generated +Note: The value specified for this parameter will be overridden and generated by New-TestResources.ps1 if $CI is specified. ```yaml @@ -113,23 +119,8 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -ResourceGroupName -Set this value to deploy directly to a Resource Group that has already been -created. - -```yaml -Type: String -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - ### -ServiceDirectory + A directory under 'sdk' in the repository root - optionally with subdirectories specified - in which to discover ARM templates named 'test-resources.json'. This can also be an absolute path or specify parent directories. @@ -147,6 +138,7 @@ Accept wildcard characters: False ``` ### -TestApplicationId + The AAD Application ID to authenticate the test runner against deployed resources. Passed to the ARM template as 'testApplicationId'. @@ -167,6 +159,7 @@ Accept wildcard characters: False ``` ### -TestApplicationSecret + Optional service principal secret (password) to authenticate the test runner against deployed resources. Passed to the ARM template as @@ -188,6 +181,7 @@ Accept wildcard characters: False ``` ### -TestApplicationOid + Service Principal Object ID of the AAD Test application. This is used to assign permissions to the AAD application so it can access tested features on the live @@ -212,6 +206,7 @@ Accept wildcard characters: False ``` ### -TenantId + The tenant ID of a service principal when a provisioner is specified. The same Tenant ID is used for Test Application and Provisioner Application. @@ -231,6 +226,7 @@ Accept wildcard characters: False ``` ### -SubscriptionId + Optional subscription ID to use for new resources when logging in as a provisioner. You can also use Set-AzContext if not provisioning. @@ -248,6 +244,7 @@ Accept wildcard characters: False ``` ### -ProvisionerApplicationId + The AAD Application ID used to provision test resources when a provisioner is specified. @@ -268,6 +265,7 @@ Accept wildcard characters: False ``` ### -ProvisionerApplicationSecret + A service principal secret (password) used to provision test resources when a provisioner is specified. @@ -288,6 +286,7 @@ Accept wildcard characters: False ``` ### -DeleteAfterHours + Optional. Positive integer number of hours from the current time to set the 'DeleteAfter' tag on the created resource group. @@ -300,7 +299,7 @@ created resource group. An optional cleanup process can delete resource groups whose "DeleteAfter" timestamp is less than the current time. -This isused for CI automation. +This is used for CI automation. ```yaml Type: Int32 @@ -315,6 +314,7 @@ Accept wildcard characters: False ``` ### -Location + Optional location where resources should be created. If left empty, the default is based on the cloud to which the template is being deployed: @@ -336,6 +336,7 @@ Accept wildcard characters: False ``` ### -Environment + Name of the cloud environment. The default is the Azure Public Cloud ('PublicCloud') @@ -353,6 +354,7 @@ Accept wildcard characters: False ``` ### -AdditionalParameters + Optional key-value pairs of parameters to pass to the ARM template(s). ```yaml @@ -368,6 +370,7 @@ Accept wildcard characters: False ``` ### -CI + Indicates the script is run as part of a Continuous Integration / Continuous Deployment (CI/CD) build (only Azure Pipelines is currently supported). @@ -384,6 +387,7 @@ Accept wildcard characters: False ``` ### -Force + Force creation of resources instead of being prompted. ```yaml @@ -398,32 +402,31 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -OutFile -Save test environment settings into a test-resources.json.env file next to test-resources.json. -File is protected via DPAPI. -Supported only on windows. -The environment file would be scoped to the current repository directory. +### -WhatIf + +Shows what would happen if the cmdlet runs. +The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) -Aliases: +Aliases: wi Required: False Position: Named -Default value: False +Default value: None Accept pipeline input: False Accept wildcard characters: False ``` -### -WhatIf -Shows what would happen if the cmdlet runs. -The cmdlet is not run. +### -Confirm + +Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) -Aliases: wi +Aliases: cf Required: False Position: Named @@ -432,13 +435,16 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -Confirm -Prompts you for confirmation before running the cmdlet. +### -OutFile + +save test environment settings into a test-resources.json.env file next to test-resources.json. +The file is protected via DPAPI. The environment file would be scoped to the current repository directory. +Note: Supported only on Windows. ```yaml Type: SwitchParameter Parameter Sets: (All) -Aliases: cf +Aliases: Required: False Position: Named @@ -448,6 +454,7 @@ Accept wildcard characters: False ``` ### CommonParameters + This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -458,5 +465,4 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ## RELATED LINKS -[Remove-TestResources.ps1]() - +[Remove-TestResources.ps1](./Remove-TestResources.ps1.md) diff --git a/eng/common/TestResources/Remove-TestResources.ps1.md b/eng/common/TestResources/Remove-TestResources.ps1.md index 7a70923dcd0d..f8f1c001df12 100644 --- a/eng/common/TestResources/Remove-TestResources.ps1.md +++ b/eng/common/TestResources/Remove-TestResources.ps1.md @@ -8,41 +8,46 @@ schema: 2.0.0 # Remove-TestResources.ps1 ## SYNOPSIS + Deletes the resource group deployed for a service directory from Azure. ## SYNTAX ### Default (Default) -``` -Remove-TestResources.ps1 [-BaseName] [-ServiceDirectory ] [-Environment ] [-Force] - [-RemoveTestResourcesRemainingArguments ] [-WhatIf] [-Confirm] [] + +```text +Remove-TestResources.ps1 [-BaseName] [-Environment ] [-Force] [-WhatIf] [-Confirm] + [] ``` ### Default+Provisioner -``` + +```text Remove-TestResources.ps1 [-BaseName] -TenantId [-SubscriptionId ] - -ProvisionerApplicationId -ProvisionerApplicationSecret [-ServiceDirectory ] - [-Environment ] [-Force] [-RemoveTestResourcesRemainingArguments ] [-WhatIf] [-Confirm] - [] + -ProvisionerApplicationId -ProvisionerApplicationSecret [-Environment ] [-Force] + [-WhatIf] [-Confirm] [] ``` ### ResourceGroup+Provisioner -``` + +```text Remove-TestResources.ps1 -ResourceGroupName -TenantId [-SubscriptionId ] - -ProvisionerApplicationId -ProvisionerApplicationSecret [-ServiceDirectory ] - [-Environment ] [-Force] [-RemoveTestResourcesRemainingArguments ] [-WhatIf] [-Confirm] - [] + -ProvisionerApplicationId -ProvisionerApplicationSecret [-Environment ] [-Force] + [-WhatIf] [-Confirm] [] ``` ### ResourceGroup -``` -Remove-TestResources.ps1 -ResourceGroupName [-ServiceDirectory ] [-Environment ] - [-Force] [-RemoveTestResourcesRemainingArguments ] [-WhatIf] [-Confirm] [] + +```text +Remove-TestResources.ps1 -ResourceGroupName [-Environment ] [-Force] [-WhatIf] [-Confirm] + [] ``` ## DESCRIPTION + Removes a resource group and all its resources previously deployed using New-TestResources.ps1. + If you are not currently logged into an account in the Az PowerShell module, you will be asked to log in with Connect-AzAccount. Alternatively, you (or a @@ -53,14 +58,17 @@ create resources. ## EXAMPLES ### EXAMPLE 1 -``` + +```text Remove-TestResources.ps1 -BaseName 'uuid123' -Force +``` + Use the currently logged-in account to delete the resource group by the name of 'rg-uuid123' -``` ### EXAMPLE 2 -``` + +```text Remove-TestResources.ps1 ` -ResourceGroupName "${env:AZURE_RESOURCEGROUP_NAME}" ` -TenantId '$(TenantId)' ` @@ -68,14 +76,16 @@ Remove-TestResources.ps1 ` -ProvisionerApplicationSecret '$(AppSecret)' ` -Force ` -Verbose ` +``` + When run in the context of an Azure DevOps pipeline, this script removes the resource group whose name is stored in the environment variable AZURE_RESOURCEGROUP_NAME. -``` ## PARAMETERS ### -BaseName + A name to use in the resource group and passed to the ARM template as 'baseName'. This will delete the resource group named 'rg-\' @@ -92,6 +102,7 @@ Accept wildcard characters: False ``` ### -ResourceGroupName + The name of the resource group to delete. ```yaml @@ -107,6 +118,7 @@ Accept wildcard characters: False ``` ### -TenantId + The tenant ID of a service principal when a provisioner is specified. ```yaml @@ -122,6 +134,7 @@ Accept wildcard characters: False ``` ### -SubscriptionId + Optional subscription ID to use for new resources when logging in as a provisioner. You can also use Set-AzContext if not provisioning. @@ -139,6 +152,7 @@ Accept wildcard characters: False ``` ### -ProvisionerApplicationId + A service principal ID to provision test resources when a provisioner is specified. ```yaml @@ -154,6 +168,7 @@ Accept wildcard characters: False ``` ### -ProvisionerApplicationSecret + A service principal secret (password) to provision test resources when a provisioner is specified. ```yaml @@ -169,8 +184,9 @@ Accept wildcard characters: False ``` ### -ServiceDirectory + A directory under 'sdk' in the repository root - optionally with subdirectories -specified - in which to discover pre removal script named 'remove-test-resources-pre.json'. +specified - specified - in which to discover pre removal script named 'remove-test-resources-pre.json'. ```yaml Type: String @@ -185,6 +201,7 @@ Accept wildcard characters: False ``` ### -Environment + Name of the cloud environment. The default is the Azure Public Cloud ('PublicCloud') @@ -202,6 +219,7 @@ Accept wildcard characters: False ``` ### -Force + Force removal of resource group without asking for user confirmation ```yaml @@ -216,22 +234,8 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -RemoveTestResourcesRemainingArguments -Captures any arguments not declared here (no parameter errors) - -```yaml -Type: Object -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - ### -WhatIf + Shows what would happen if the cmdlet runs. The cmdlet is not run. @@ -248,6 +252,7 @@ Accept wildcard characters: False ``` ### -Confirm + Prompts you for confirmation before running the cmdlet. ```yaml @@ -263,6 +268,7 @@ Accept wildcard characters: False ``` ### CommonParameters + This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -273,5 +279,4 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ## RELATED LINKS -[New-TestResources.ps1]() - +[New-TestResources.ps1](./New-TestResources.ps1.md) diff --git a/eng/common/TestResources/remove-test-resources.yml b/eng/common/TestResources/remove-test-resources.yml index 01e9f64d5516..34beecd3cb81 100644 --- a/eng/common/TestResources/remove-test-resources.yml +++ b/eng/common/TestResources/remove-test-resources.yml @@ -27,7 +27,7 @@ steps: eng/common/TestResources/Remove-TestResources.ps1 ` -ResourceGroupName "${env:AZURE_RESOURCEGROUP_NAME}" ` - -ServiceDirectory "${{ parameters.ServiceDirectory }}" ` + -ServiceDirectory ${{ parameters.ServiceDirectory }} ` @subscriptionConfiguration ` -Force ` -Verbose diff --git a/eng/common/pipelines/templates/steps/create-pull-request.yml b/eng/common/pipelines/templates/steps/create-pull-request.yml index 7b3e3a75f456..63cbe4d0f0e5 100644 --- a/eng/common/pipelines/templates/steps/create-pull-request.yml +++ b/eng/common/pipelines/templates/steps/create-pull-request.yml @@ -71,6 +71,7 @@ steps: - task: PowerShell@2 displayName: Tag a Reviewer on PR condition: and(succeeded(), eq(variables['HasChanges'], 'true')) + continueOnError: true inputs: pwsh: true workingDirectory: ${{ parameters.WorkingDirectory }} diff --git a/eng/common/pipelines/templates/steps/get-pr-owners.yml b/eng/common/pipelines/templates/steps/get-pr-owners.yml index a80d5b83b2de..e3739602b229 100644 --- a/eng/common/pipelines/templates/steps/get-pr-owners.yml +++ b/eng/common/pipelines/templates/steps/get-pr-owners.yml @@ -18,12 +18,20 @@ steps: --kusto-database-var KUSTO_DB ` --kusto-table-var KUSTO_TABLE ` --identity "$(Build.QueuedBy)" - $resolvedIdentity = $result[-1] | ConvertFrom-Json - Write-Host $resolvedIdentity + $resolvedIdentity = "" + try { $resolvedIdentity = $result[-1] | ConvertFrom-Json } catch {} - Write-Output "##vso[task.setvariable variable=${{ parameters.TargetVariable }}]$($resolvedIdentity.GithubUserName)" + if($resolvedIdentity) { + Write-Host $resolvedIdentity + + Write-Host "##vso[task.setvariable variable=${{ parameters.TargetVariable }}]$($resolvedIdentity.GithubUserName)" + } + else { + Write-Host "Unable to locate a github user for identity $(Build.QueuedBy)" + } displayName: 'Resolving Queuing User' + continueOnError: true workingDirectory: $(Build.SourcesDirectory)/tools_repo/tools/notification-configuration/identity-resolver env: APP_ID: $(notification-aad-app-id) @@ -41,6 +49,6 @@ steps: $originalValue = "$(${{ parameters.TargetVariable }})" $result = $(Build.SourcesDirectory)/eng/common/scripts/get-codeowners.ps1 -TargetDirectory /sdk/${{ parameters.ServiceDirectory }}/ -RootDirectory $(Build.SourcesDirectory) if ($result) { - Write-Output "##vso[task.setvariable variable=${{ parameters.TargetVariable }}]$originalValue,$result" + Write-Host "##vso[task.setvariable variable=${{ parameters.TargetVariable }}]$originalValue,$result" } displayName: Add CodeOwners if Present \ No newline at end of file diff --git a/eng/common/pipelines/templates/steps/verify-links.yml b/eng/common/pipelines/templates/steps/verify-links.yml index c9d76c99787e..2cc38d4767b7 100644 --- a/eng/common/pipelines/templates/steps/verify-links.yml +++ b/eng/common/pipelines/templates/steps/verify-links.yml @@ -14,6 +14,5 @@ steps: -rootUrl "file://$(Build.SourcesDirectory)/${{ parameters.Directory }}" -recursive: $false -ignoreLinksFile ${{ parameters.IgnoreLinksFile }} - -branchReplaceRegex "^($env:SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI.*/(?:blob|tree)/)master(/.*)$" + -branchReplaceRegex "($env:SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI.*/blob/)master(/.*)" -branchReplacementName $env:SYSTEM_PULLREQUEST_SOURCECOMMITID - -devOpsLogging: $true diff --git a/eng/common/scripts/Verify-Links.ps1 b/eng/common/scripts/Verify-Links.ps1 index 946655b3fcd9..0742020ec5d4 100644 --- a/eng/common/scripts/Verify-Links.ps1 +++ b/eng/common/scripts/Verify-Links.ps1 @@ -14,7 +14,7 @@ param ( # list of http status codes count as broken links. Defaults to 400, 401, 404, SocketError.HostNotFound = 11001, SocketError.NoData = 11004 [array] $errorStatusCodes = @(400, 401, 404, 11001, 11004), # regex to check if the link needs to be replaced - [string] $branchReplaceRegex = "^(https://github.com/.*/(?:blob|tree)/)master(/.*)$", + [string] $branchReplaceRegex = "(https://github.com/.*/blob/)master(/.*)", # the substitute branch name or SHA commit [string] $branchReplacementName = "", # flag to allow checking against azure sdk link guidance. @@ -62,18 +62,6 @@ function LogWarning } } -function LogError -{ - if ($devOpsLogging) - { - Write-Host "##vso[task.logissue type=error]$args" - } - else - { - Write-Error "$args" - } -} - function ResolveUri ([System.Uri]$referralUri, [string]$link) { # If the link is mailto, skip it. @@ -135,9 +123,6 @@ function ParseLinks([string]$baseUri, [string]$htmlContent) function CheckLink ([System.Uri]$linkUri) { if ($checkedLinks.ContainsKey($linkUri)) { - if (!$checkedLinks[$linkUri]) { - LogWarning "broken link $linkUri" - } return $checkedLinks[$linkUri] } @@ -260,6 +245,7 @@ if ($PSVersionTable.PSVersion.Major -lt 6) { LogWarning "Some web requests will not work in versions of PS earlier then 6. You are running version $($PSVersionTable.PSVersion)." } +$badLinks = @(); $ignoreLinks = @(); if (Test-Path $ignoreLinksFile) { @@ -268,7 +254,6 @@ if (Test-Path $ignoreLinksFile) $checkedPages = @{}; $checkedLinks = @{}; -$badLinks = @{}; $pageUrisToCheck = new-object System.Collections.Queue foreach ($url in $urls) { @@ -284,12 +269,13 @@ while ($pageUrisToCheck.Count -ne 0) $linkUris = GetLinks $pageUri Write-Host "Found $($linkUris.Count) links on page $pageUri"; - $badLinksPerPage = @(); + foreach ($linkUri in $linkUris) { $linkUri = ReplaceGithubLink $linkUri + $isLinkValid = CheckLink $linkUri - if (!$isLinkValid -and !$badLinksPerPage.Contains($linkUri)) { - $badLinksPerPage += $linkUri + if (!$isLinkValid) { + $script:badLinks += $linkUri } if ($recursive -and $isLinkValid) { if ($linkUri.ToString().StartsWith($baseUrl) -and !$checkedPages.ContainsKey($linkUri)) { @@ -297,25 +283,9 @@ while ($pageUrisToCheck.Count -ne 0) } } } - if ($badLinksPerPage.Count -gt 0) { - $badLinks[$pageUri] = $badLinksPerPage - } } -if ($badLinks.Count -gt 0) { - Write-Host "Summary of broken links:" -} -foreach ($pageLink in $badLinks.Keys) { - Write-Host "'$pageLink' has $($badLinks[$pageLink].Count) broken link(s):" - foreach ($brokenLink in $badLinks[$pageLink]) { - Write-Host " $brokenLink" - } -} +Write-Host "Found $($checkedLinks.Count) links with $($badLinks.Count) broken" +$badLinks | ForEach-Object { Write-Host " $_" } -if ($badLinks.Count -gt 0) { - LogError "Found $($checkedLinks.Count) links with $($badLinks.Count) page(s) broken." -} -else { - Write-Host "Found $($checkedLinks.Count) links. No broken links found." -} exit $badLinks.Count diff --git a/eng/common/scripts/add-pullrequest-reviewers.ps1 b/eng/common/scripts/add-pullrequest-reviewers.ps1 index a80d79485f3b..3198dcb40d2c 100644 --- a/eng/common/scripts/add-pullrequest-reviewers.ps1 +++ b/eng/common/scripts/add-pullrequest-reviewers.ps1 @@ -18,6 +18,32 @@ param( $AuthToken ) +function AddMembers($memberName, $additionSet) { + $headers = @{ + Authorization = "bearer $AuthToken" + } + $uri = "https://api.github.com/repos/$RepoOwner/$RepoName/pulls/$PRNumber/requested_reviewers" + $errorOccurred = $false + + foreach ($id in $additionSet) { + try { + $postResp = @{} + $postResp[$memberName] = @($id) + $postResp = $postResp | ConvertTo-Json + + Write-Host $postResp + $resp = Invoke-RestMethod -Method Post -Headers $headers -Body $postResp -Uri $uri -MaximumRetryCount 3 + $resp | Write-Verbose + } + catch { + Write-Host "Error attempting to add $user `n$_" + $errorOccurred = $true + } + } + + return $errorOccurred +} + # at least one of these needs to be populated if (-not $GitHubUsers -and -not $GitHubTeams) { Write-Host "No user provided for addition, exiting." @@ -27,54 +53,9 @@ if (-not $GitHubUsers -and -not $GitHubTeams) { $userAdditions = @($GitHubUsers.Split(",") | % { $_.Trim() } | ? { return $_ }) $teamAdditions = @($GitHubTeams.Split(",") | % { $_.Trim() } | ? { return $_ }) -$headers = @{ - Authorization = "bearer $AuthToken" -} -$uri = "https://api.github.com/repos/$RepoOwner/$RepoName/pulls/$PRNumber/requested_reviewers" +$errorsOccurredAddingUsers = AddMembers -memberName "reviewers" -additionSet $userAdditions +$errorsOccurredAddingTeams = AddMembers -memberName "team_reviewers" -additionSet $teamAdditions -try { - $resp = Invoke-RestMethod -Headers $headers $uri -MaximumRetryCount 3 -} -catch { - Write-Error "Invoke-RestMethod [$uri] failed with exception:`n$_" +if ($errorsOccurredAddingUsers -or $errorsOccurredAddingTeams) { exit 1 } - -# the response object takes this form: https://developer.github.com/v3/pulls/review_requests/#response-1 -# before we can push a new reviewer, we need to pull the simple Ids out of the complex objects that came back in the response -$userReviewers = @($resp.users | % { return $_.login }) -$teamReviewers = @($resp.teams | % { return $_.slug }) - -if (!$userReviewers) { $modifiedUserReviewers = @() } else { $modifiedUserReviewers = $userReviewers.Clone() } -$modifiedUserReviewers += ($userAdditions | ? { !$modifiedUserReviewers.Contains($_) }) - -if ($teamReviewers) { $modifiedTeamReviewers = @() } else { $modifiedTeamReviewers = $teamReviewers.Clone() } -$modifiedTeamReviewers += ($teamAdditions | ? { !$modifiedTeamReviewers.Contains($_) }) - -$detectedUserDiffs = Compare-Object -ReferenceObject $userReviewers -DifferenceObject $modifiedUserReviewers -$detectedTeamDiffs = Compare-Object -ReferenceObject $teamReviewers -DifferenceObject $modifiedTeamReviewers - -# Compare-Object returns values when there is a difference between the comparied objects. -# we only want to run the update if there IS a difference. -if ($detectedUserDiffs -or $detectedTeamDiffs) { - $postResp = @{} - - if ($modifiedUserReviewers) { $postResp["reviewers"] = $modifiedUserReviewers } - if ($modifiedTeamReviewers) { $postResp["team_reviewers"] = $modifiedTeamReviewers } - - $postResp = $postResp | ConvertTo-Json - - try { - Write-Host $postResp - $resp = Invoke-RestMethod -Method Post -Headers $headers -Body $postResp -Uri $uri -MaximumRetryCount 3 - $resp | Write-Verbose - } - catch { - Write-Error "Unable to update PR reviewers. `n$_" - } -} -else { - $results = $GitHubUsers + $GitHubTeams - Write-Host "Reviewers $results already added. Exiting." - exit(0) -}